OSDN Git Service

PresetColorを廃止する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / View / MainFormLabels.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.Windows.Forms;\r
19 using KancolleSniffer.Model;\r
20 \r
21 namespace KancolleSniffer.View\r
22 {\r
23     /// <summary>\r
24     /// 艦娘名の横幅\r
25     /// 艦娘名のラベルのZ-orderは最下なので名前が長すぎると右隣のラベルの下に隠れるが、\r
26     /// 空装備マークはラベルの右端に表示するので右端が見えるように縮める必要がある。\r
27     /// </summary>\r
28     public enum ShipNameWidth\r
29     {\r
30         MainPanel = 92, // 左端2 HP右端129幅35 129-2-35=92\r
31         AkashiTimer = 53, // 左端2 タイマー左端55 55-2=53 漢字4文字\r
32         NDock = 65, // 左端29 終了時刻右端138幅47 138-47-29=62 空装備マークなし漢字5文字65\r
33         RepairList = 65, // 左端9 時間左端75 75-9=66 漢字5文字65\r
34         RepairListFull = 73, // 左端10 HP右端118幅35 118-10-35=73\r
35         ShipList = 81, // 左端10 HP右端126幅35 126-10-35=81\r
36         GroupConfig = 80, // 左端10 レベル左端90 90-10=80\r
37         Combined = 53, // 左端2 HP右端88幅35 88-2-35=51 空装備マーク犠牲 漢字4文字53\r
38         BattleResult = 65, // 左端2 HP右端101幅35 101-1-35=65\r
39         CiShipName = 65, // 左端168幅236 236-168=68 漢字5文字65\r
40         Max = int.MaxValue\r
41     }\r
42 \r
43     public class MainFormPanels\r
44     {\r
45         public Control PanelShipInfo { get; set; }\r
46         public Control Panel7Ships { get; set; }\r
47         public Control PanelCombinedFleet { get; set; }\r
48         public Control PanelNDock { get; set; }\r
49     }\r
50 \r
51     public class MainFormLabels\r
52     {\r
53         private readonly ShipLabel[][] _shipLabels = new ShipLabel[ShipInfo.MemberCount][];\r
54         private readonly ShipLabel[][] _shipLabels7 = new ShipLabel[7][];\r
55         private readonly ShipLabel[][] _combinedLabels = new ShipLabel[ShipInfo.MemberCount * 2][];\r
56         private readonly ShipLabel[] _akashiTimers = new ShipLabel[ShipInfo.MemberCount];\r
57         private readonly ShipLabel[] _akashiTimers7 = new ShipLabel[ShipInfo.MemberCount];\r
58         private readonly ShipLabel[][] _ndockLabels = new ShipLabel[DockInfo.DockCount][];\r
59         private readonly List<ShipLabel> _hpLabels = new List<ShipLabel>();\r
60         private readonly MainFormPanels _panels;\r
61         public bool ShowHpInPercent { get; private set; }\r
62 \r
63         public MainFormLabels(MainFormPanels panels)\r
64         {\r
65             _panels = panels;\r
66         }\r
67 \r
68         public void CreateAllShipLabels(EventHandler onClick)\r
69         {\r
70             CreateAkashiTimers(_panels.PanelShipInfo);\r
71             CreateShipLabels(_panels.PanelShipInfo, onClick);\r
72             CreateAkashiTimers7(_panels.Panel7Ships);\r
73             CreateShipLabels7(_panels.Panel7Ships, onClick);\r
74             CreateCombinedShipLabels(_panels.PanelCombinedFleet, onClick);\r
75         }\r
76 \r
77         public void CreateNDockLabels(EventHandler onClick)\r
78         {\r
79             CreateNDockLabels(_panels.PanelNDock, onClick);\r
80         }\r
81 \r
82         private void CreateShipLabels(Control parent, EventHandler onClick)\r
83         {\r
84             CreateShipLabels(parent, onClick, _shipLabels, 16);\r
85         }\r
86 \r
87         private void CreateShipLabels7(Control parent, EventHandler onClick)\r
88         {\r
89             CreateShipLabels(parent, onClick, _shipLabels7, 14);\r
90         }\r
91 \r
92         private void CreateShipLabels(Control parent, EventHandler onClick, ShipLabel[][] shipLabels, int lineHeight)\r
93         {\r
94             parent.SuspendLayout();\r
95             const int top = 1, height = 12;\r
96             ShipLabel[] headings;\r
97             parent.Controls.AddRange(headings = new[]\r
98             {\r
99                 new ShipLabel {Location = new Point(109, top), Text = "HP", AutoSize = true},\r
100                 new ShipLabel {Location = new Point(128, top), Text = "cond", AutoSize = true},\r
101                 new ShipLabel {Location = new Point(162, top), Text = "Lv", AutoSize = true},\r
102                 new ShipLabel {Location = new Point(194, top), Text = "Exp", AutoSize = true},\r
103                 new ShipLabel {Location = new Point(0, 1), Size = new Size(parent.Width, lineHeight - 1)}\r
104             });\r
105             foreach (var label in headings)\r
106             {\r
107                 Scaler.Scale(label);\r
108                 label.BackColor = ShipLabel.ColumnColors[1];\r
109             }\r
110             for (var i = 0; i < shipLabels.Length; i++)\r
111             {\r
112                 var y = top + lineHeight * (i + 1);\r
113                 parent.Controls.AddRange(shipLabels[i] = new[]\r
114                 {\r
115                     new ShipLabel\r
116                     {\r
117                         Location = new Point(129, y),\r
118                         AutoSize = true,\r
119                         AnchorRight = true,\r
120                         MinimumSize = new Size(0, lineHeight),\r
121                         TextAlign = ContentAlignment.MiddleLeft,\r
122                         Cursor = Cursors.Hand\r
123                     },\r
124                     new ShipLabel\r
125                     {\r
126                         Location = new Point(131, y),\r
127                         Size = new Size(24, lineHeight),\r
128                         TextAlign = ContentAlignment.MiddleRight\r
129                     },\r
130                     new ShipLabel\r
131                     {\r
132                         Location = new Point(155, y + 2),\r
133                         Size = new Size(24, height),\r
134                         TextAlign = ContentAlignment.MiddleRight\r
135                     },\r
136                     new ShipLabel\r
137                     {\r
138                         Location = new Point(176, y + 2),\r
139                         Size = new Size(42, height),\r
140                         TextAlign = ContentAlignment.MiddleRight\r
141                     },\r
142                     new ShipLabel {Location = new Point(2, y + 2), AutoSize = true}, // 名前のZ-orderを下に\r
143                     new ShipLabel {Location = new Point(0, y), Size = new Size(parent.Width, lineHeight)}\r
144                 });\r
145                 foreach (var label in shipLabels[i])\r
146                 {\r
147                     Scaler.Scale(label);\r
148                     label.BackColor = ShipLabel.ColumnColors[i % 2];\r
149                     label.Tag = i;\r
150                     label.Click += onClick;\r
151                 }\r
152                 var hpLabel = shipLabels[i][0];\r
153                 _hpLabels.Add(hpLabel);\r
154                 hpLabel.DoubleClick += HpLabelClickHandler;\r
155             }\r
156             headings[0].Cursor = Cursors.Hand;\r
157             headings[0].Click += HpLabelClickHandler;\r
158             parent.ResumeLayout();\r
159         }\r
160 \r
161         private void HpLabelClickHandler(object sender, EventArgs ev)\r
162         {\r
163             ToggleHpPercent();\r
164         }\r
165 \r
166         public void ToggleHpPercent()\r
167         {\r
168             ShowHpInPercent = !ShowHpInPercent;\r
169             foreach (var label in _hpLabels)\r
170                 label.ToggleHpPercent();\r
171         }\r
172 \r
173         public void SetShipLabels(IReadOnlyList<ShipStatus> ships)\r
174         {\r
175             SetShipLabels(ships, ships.Count == 7 ? _shipLabels7 : _shipLabels);\r
176         }\r
177 \r
178         public void SetShipLabels(IReadOnlyList<ShipStatus> ships, ShipLabel[][] shipLabels)\r
179         {\r
180             for (var i = 0; i < shipLabels.Length; i++)\r
181             {\r
182                 var labels = shipLabels[i];\r
183                 var ship = i < ships.Count ? ships[i] : null;\r
184                 labels[0].SetHp(ship);\r
185                 labels[1].SetCond(ship);\r
186                 labels[2].SetLevel(ship);\r
187                 labels[3].SetExpToNext(ship);\r
188                 labels[4].SetName(ship, ShipNameWidth.MainPanel);\r
189             }\r
190         }\r
191 \r
192         public void CreateCombinedShipLabels(Control parent, EventHandler onClick)\r
193         {\r
194             parent.SuspendLayout();\r
195             const int top = 1, lh = 16;\r
196             const int parentWidth = 220; // parent.Widthを使うとDPIスケーリング時に計算がくるうので\r
197             ShipLabel[] headings;\r
198             parent.Controls.AddRange(headings = new[]\r
199             {\r
200                 new ShipLabel {Location = new Point(68, top), Text = "HP", AutoSize = true},\r
201                 new ShipLabel {Location = new Point(86, top), Text = "cnd", AutoSize = true},\r
202                 new ShipLabel {Location = new Point(177, top), Text = "HP", AutoSize = true},\r
203                 new ShipLabel {Location = new Point(195, top), Text = "cnd", AutoSize = true},\r
204                 new ShipLabel {Location = new Point(0, 1), Size = new Size(parentWidth, lh - 1)}\r
205             });\r
206             foreach (var label in headings)\r
207             {\r
208                 Scaler.Scale(label);\r
209                 label.BackColor = ShipLabel.ColumnColors[1];\r
210             }\r
211             for (var i = 0; i < _combinedLabels.Length; i++)\r
212             {\r
213                 var x = parentWidth / 2 * (i / ShipInfo.MemberCount);\r
214                 var y = top + lh * (i % ShipInfo.MemberCount + 1);\r
215                 parent.Controls.AddRange(_combinedLabels[i] = new[]\r
216                 {\r
217                     new ShipLabel\r
218                     {\r
219                         Location = new Point(x + 88, y),\r
220                         AutoSize = true,\r
221                         AnchorRight = true,\r
222                         MinimumSize = new Size(0, lh),\r
223                         TextAlign = ContentAlignment.MiddleLeft,\r
224                         Cursor = Cursors.Hand\r
225                     },\r
226                     new ShipLabel\r
227                     {\r
228                         Location = new Point(x + 85, y),\r
229                         Size = new Size(24, lh),\r
230                         TextAlign = ContentAlignment.MiddleRight\r
231                     },\r
232                     new ShipLabel {Location = new Point(x + 2, y + 2), AutoSize = true}, // 名前のZ-orderを下に\r
233                     new ShipLabel {Location = new Point(x, y), Size = new Size(parentWidth / 2, lh)}\r
234                 });\r
235                 foreach (var label in _combinedLabels[i])\r
236                 {\r
237                     Scaler.Scale(label);\r
238                     label.BackColor = ShipLabel.ColumnColors[i % 2];\r
239                     label.Tag = i;\r
240                     label.Click += onClick;\r
241                 }\r
242                 var hpLabel = _combinedLabels[i][0];\r
243                 _hpLabels.Add(hpLabel);\r
244                 hpLabel.DoubleClick += HpLabelClickHandler;\r
245             }\r
246             headings[0].Cursor = headings[2].Cursor = Cursors.Hand;\r
247             headings[0].Click += HpLabelClickHandler;\r
248             headings[2].Click += HpLabelClickHandler;\r
249             parent.ResumeLayout();\r
250         }\r
251 \r
252         public void SetCombinedShipLabels(IReadOnlyList<ShipStatus> first, IReadOnlyList<ShipStatus> second)\r
253         {\r
254             for (var i = 0; i < _combinedLabels.Length; i++)\r
255             {\r
256                 var idx = i % ShipInfo.MemberCount;\r
257                 var ships = i < ShipInfo.MemberCount ? first : second;\r
258                 var labels = _combinedLabels[i];\r
259                 var s = idx < ships.Count ? ships[idx] : null;\r
260                 labels[0].SetHp(s);\r
261                 labels[1].SetCond(s);\r
262                 labels[2].SetName(s, ShipNameWidth.Combined);\r
263             }\r
264         }\r
265 \r
266         public void CreateAkashiTimers(Control parent)\r
267         {\r
268             CreateAkashiTimers(parent, _akashiTimers, 16);\r
269         }\r
270 \r
271         public void CreateAkashiTimers7(Control parent)\r
272         {\r
273             CreateAkashiTimers(parent, _akashiTimers7, 14);\r
274         }\r
275 \r
276         public void CreateAkashiTimers(Control parent, ShipLabel[] timerLabels, int lineHeight)\r
277         {\r
278             parent.SuspendLayout();\r
279             for (var i = 0; i < timerLabels.Length; i++)\r
280             {\r
281                 const int x = 55;\r
282                 var y = 3 + lineHeight * (i + 1);\r
283                 ShipLabel label;\r
284                 parent.Controls.Add(\r
285                     label = timerLabels[i] =\r
286                         new ShipLabel\r
287                         {\r
288                             Location = new Point(x, y),\r
289                             Size = new Size(31, 12),\r
290                             TextAlign = ContentAlignment.TopRight\r
291                         });\r
292                 label.BackColor = ShipLabel.ColumnColors[i % 2];\r
293             }\r
294             foreach (var label in timerLabels)\r
295                 Scaler.Scale(label);\r
296             parent.ResumeLayout();\r
297         }\r
298 \r
299         public void AdjustAkashiTimers()\r
300         {\r
301             AdjustAkashiTimers(_akashiTimers, 16);\r
302             AdjustAkashiTimers(_akashiTimers7, 14);\r
303         }\r
304 \r
305         public void AdjustAkashiTimers(ShipLabel[] timers, int lineHeight)\r
306         {\r
307             if (Scaler.ScaleHeight(1f) < 1.2)\r
308                 return;\r
309             for (var i = 0; i < timers.Length; i++)\r
310             {\r
311                 const int x = 55;\r
312                 var y = 3 + lineHeight * (i + 1);\r
313                 timers[i].Location = Scaler.Move(-3, 0, x, y);\r
314                 timers[i].Size = new Size(Scaler.ScaleWidth(31) + 1, Scaler.ScaleWidth(12));\r
315             }\r
316         }\r
317 \r
318         public void SetAkashiTimer(IReadOnlyList<ShipStatus> ships, AkashiTimer.RepairSpan[] timers)\r
319         {\r
320             if (ships.Count == 7)\r
321             {\r
322                 SetAkashiTimer(ships, timers, _akashiTimers7, _shipLabels7);\r
323             }\r
324             else\r
325             {\r
326                 SetAkashiTimer(ships, timers, _akashiTimers, _shipLabels);\r
327             }\r
328         }\r
329 \r
330         public void SetAkashiTimer(IReadOnlyList<ShipStatus> ships, AkashiTimer.RepairSpan[] timers,\r
331             ShipLabel[] timerLabels, ShipLabel[][] shipLabels)\r
332         {\r
333             var shortest = -1;\r
334             for (var i = 0; i < timers.Length; i++)\r
335             {\r
336                 if (timers[i].Span <= TimeSpan.Zero)\r
337                     continue;\r
338                 if (shortest == -1 || timers[i].Span < timers[shortest].Span)\r
339                     shortest = i;\r
340             }\r
341             for (var i = 0; i < timerLabels.Length; i++)\r
342             {\r
343                 var label = timerLabels[i];\r
344                 var labelHp = shipLabels[i][0];\r
345                 var labelName = shipLabels[i][4];\r
346                 if (i >= timers.Length || timers[i].Span == TimeSpan.MinValue)\r
347                 {\r
348                     label.Visible = false;\r
349                     labelHp.ForeColor = Control.DefaultForeColor;\r
350                     continue;\r
351                 }\r
352                 var timer = timers[i];\r
353                 var stat = ships[i];\r
354                 label.Visible = true;\r
355                 label.Text = timer.Span.ToString(@"mm\:ss");\r
356                 label.ForeColor = Control.DefaultForeColor;\r
357                 labelName.SetName(stat, ShipNameWidth.AkashiTimer);\r
358                 if (timer.Diff == 0)\r
359                 {\r
360                     labelHp.ForeColor = Control.DefaultForeColor;\r
361                     continue;\r
362                 }\r
363                 if (i == shortest)\r
364                     label.ForeColor = CUDColors.Red;\r
365                 labelHp.SetHp(stat.NowHp + timer.Diff, stat.MaxHp);\r
366                 labelHp.ForeColor = Color.DimGray;\r
367             }\r
368         }\r
369 \r
370         public void CreateNDockLabels(Control parent, EventHandler onClick)\r
371         {\r
372             const int lh = 15;\r
373             for (var i = 0; i < _ndockLabels.Length; i++)\r
374             {\r
375                 var y = i * lh;\r
376                 parent.Controls.AddRange(\r
377                     _ndockLabels[i] = new[]\r
378                     {\r
379                         new ShipLabel\r
380                         {\r
381                             Location = new Point(138, y + 2),\r
382                             AutoSize = true,\r
383                             AnchorRight = true,\r
384                             MinimumSize = new Size(0, lh),\r
385                             TextAlign = ContentAlignment.MiddleLeft,\r
386                             Cursor = Cursors.Hand\r
387                         },\r
388                         new ShipLabel {Location = new Point(29, y + 3), AutoSize = true} // 名前のZ-orderを下に\r
389                     });\r
390                 foreach (var label in _ndockLabels[i])\r
391                 {\r
392                     Scaler.Scale(label);\r
393                     label.Click += onClick;\r
394                 }\r
395             }\r
396         }\r
397 \r
398         public void SetNDockLabels(NameAndTimer[] ndock)\r
399         {\r
400             for (var i = 0; i < _ndockLabels.Length; i++)\r
401                 _ndockLabels[i][1].SetName(ndock[i].Name, ShipNameWidth.NDock);\r
402         }\r
403 \r
404         public void SetNDockTimer(int dock, AlarmTimer timer, DateTime now, bool finishTime)\r
405         {\r
406             var label = _ndockLabels[dock][0];\r
407             label.ForeColor = timer.IsFinished(now) ? CUDColors.Red : Color.Black;\r
408             label.Text = timer.ToString(now, finishTime);\r
409         }\r
410     }\r
411 }