1 // Copyright (C) 2014, 2015 Kazuhiro Fujieda <fujieda@users.osdn.me>
\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
7 // http://www.apache.org/licenses/LICENSE-2.0
\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
16 using System.Collections.Generic;
\r
17 using System.Drawing;
\r
18 using System.Windows.Forms;
\r
19 using KancolleSniffer.Model;
\r
21 namespace KancolleSniffer.View.MainWindow
\r
23 public class ShipListPanels
\r
25 private const int PanelWidth = 220;
\r
27 private readonly Panel _combined = new Panel
\r
29 Location = new Point(0, 0),
\r
30 Size = new Size(PanelWidth, 113),
\r
34 private readonly Panel _7Ships = new Panel
\r
36 Location = new Point(0, 0),
\r
37 Size = new Size(PanelWidth, 113),
\r
41 private readonly ShipLabelLines _shipLines;
\r
42 private readonly ShipLabelLines _shipLines7;
\r
43 private readonly CombinedShipLines _combinedLines = new CombinedShipLines();
\r
44 private readonly HpToggle _hpToggle = new HpToggle();
\r
46 public bool ShowHpInPercent => _hpToggle.InPercent;
\r
48 public ShipListPanels(Control parent, EventHandler onClick)
\r
50 _shipLines = new ShipLabelLines(ShipInfo.MemberCount, 16);
\r
51 _shipLines7 = new ShipLabelLines(7, 14);
\r
52 parent.Controls.AddRange(new Control[] {_combined, _7Ships});
\r
53 _shipLines.Create(parent, _hpToggle, onClick);
\r
54 _shipLines7.Create(_7Ships, _hpToggle, onClick);
\r
55 _combinedLines.Create(_combined, _hpToggle, onClick);
\r
58 public void ToggleHpPercent()
\r
60 _hpToggle.ToggleHpPercent();
\r
63 private class HpToggle
\r
65 private readonly List<ShipLabel.Hp> _labels = new List<ShipLabel.Hp>();
\r
66 public bool InPercent { get; private set; }
\r
68 public void SetClickHandler(Control label)
\r
70 label.Click += LabelClickHandler;
\r
73 public void AddHpLabel(ShipLabel.Hp label)
\r
76 label.DoubleClick += LabelClickHandler;
\r
79 private void LabelClickHandler(object sender, EventArgs ev)
\r
84 public void ToggleHpPercent()
\r
86 InPercent = !InPercent;
\r
87 foreach (var label in _labels)
\r
88 label.ToggleHpPercent();
\r
92 public void SetShipLabels(IReadOnlyList<ShipStatus> ships)
\r
94 _combined.Visible = false;
\r
95 if (ships.Count == 7)
\r
97 _7Ships.Visible = true;
\r
98 _shipLines7.Set(ships);
\r
102 _7Ships.Visible = false;
\r
103 _shipLines.Set(ships);
\r
107 public void SetCombinedShipLabels(IReadOnlyList<ShipStatus> first, IReadOnlyList<ShipStatus> second)
\r
109 _combined.Visible = true;
\r
110 _combinedLines.Set(first, second);
\r
113 public void SetAkashiTimer(IReadOnlyList<ShipStatus> ships, AkashiTimer.RepairSpan[] timers)
\r
115 (ships.Count == 7 ? _shipLines7 : _shipLines).SetAkashiTimer(ships, timers);
\r
118 private class ShipLabelLines
\r
120 private readonly int _lineHeight;
\r
121 private readonly ShipLabels[] _shipLines;
\r
122 private readonly AkashiTimerLabels _akashiTimerLabels;
\r
124 private const int Top = 1;
\r
125 private const int LabelHeight = 12;
\r
127 public ShipLabelLines(int lines, int lineHeight)
\r
129 _shipLines = new ShipLabels[lines];
\r
130 _akashiTimerLabels = new AkashiTimerLabels(lineHeight, _shipLines);
\r
131 _lineHeight = lineHeight;
\r
134 public void Create(Control parent, HpToggle hpToggle, EventHandler onClick)
\r
136 parent.SuspendLayout();
\r
137 _akashiTimerLabels.Create(parent);
\r
138 CreateHeader(parent, hpToggle);
\r
139 for (var i = 0; i < _shipLines.Length; i++)
\r
141 var y = Top + _lineHeight * (i + 1);
\r
142 var labels = _shipLines[i] = new ShipLabels
\r
144 Name = new ShipLabel.Name(new Point(2, y + 2), ShipNameWidth.MainPanel),
\r
145 Hp = new ShipLabel.Hp(new Point(129, y), _lineHeight),
\r
146 Cond = new ShipLabel.Cond(new Point(131, y), _lineHeight),
\r
147 Level = new ShipLabel.Level(new Point(155, y + 2), LabelHeight),
\r
148 Exp = new ShipLabel.Exp(new Point(176, y + 2), LabelHeight),
\r
149 BackGround = new Label {Location = new Point(0, y), Size = new Size(PanelWidth, _lineHeight)}
\r
151 labels.Arrange(parent, CustomColors.ColumnColors.DarkFirst(i));
\r
152 labels.SetClickHandler(onClick);
\r
154 hpToggle.AddHpLabel(labels.Hp);
\r
156 parent.ResumeLayout();
\r
159 private void CreateHeader(Control parent, HpToggle hpToggle)
\r
161 var headings = new Control[]
\r
163 new Label {Location = new Point(109, Top), Text = "HP", AutoSize = true},
\r
164 new Label {Location = new Point(128, Top), Text = "cond", AutoSize = true},
\r
165 new Label {Location = new Point(162, Top), Text = "Lv", AutoSize = true},
\r
166 new Label {Location = new Point(194, Top), Text = "Exp", AutoSize = true},
\r
167 new Label {Location = new Point(0, 1), Size = new Size(PanelWidth, _lineHeight - 1)}
\r
169 parent.Controls.AddRange(headings);
\r
170 foreach (var control in headings)
\r
171 control.BackColor = CustomColors.ColumnColors.Bright;
\r
172 headings[0].Cursor = Cursors.Hand;
\r
173 hpToggle.SetClickHandler(headings[0]);
\r
176 public void Set(IReadOnlyList<ShipStatus> ships)
\r
178 for (var i = 0; i < _shipLines.Length; i++)
\r
180 var labels = _shipLines[i];
\r
181 if (i >= ships.Count)
\r
186 labels.Set(ships[i]);
\r
190 public void SetAkashiTimer(IReadOnlyList<ShipStatus> ships, AkashiTimer.RepairSpan[] timers) =>
\r
191 _akashiTimerLabels.SetAkashiTimer(ships, timers);
\r
194 private class AkashiTimerLabels
\r
196 private readonly ShipLabels[] _shipLines;
\r
197 private readonly Label[] _timerLabels = new Label[ShipInfo.MemberCount];
\r
198 private readonly int _lineHeight;
\r
199 private int _originalLeft;
\r
201 public AkashiTimerLabels(int lineHeight, ShipLabels[] shipLabels)
\r
203 _shipLines = shipLabels;
\r
204 _lineHeight = lineHeight;
\r
207 public void Create(Control parent)
\r
210 for (var i = 0; i < _timerLabels.Length; i++)
\r
212 var y = 3 + _lineHeight * (i + 1);
\r
214 parent.Controls.Add(
\r
215 label = _timerLabels[i] =
\r
218 Location = new Point(x, y),
\r
220 TextAlign = ContentAlignment.TopRight
\r
222 label.BackColor = CustomColors.ColumnColors.DarkFirst(i);
\r
226 public void SetAkashiTimer(IReadOnlyList<ShipStatus> ships, AkashiTimer.RepairSpan[] timers)
\r
228 var shortest = ShortestSpanIndex(timers);
\r
229 for (var i = 0; i < _timerLabels.Length; i++)
\r
231 var label = _timerLabels[i];
\r
232 var shipLabels = _shipLines[i];
\r
233 if (i >= timers.Length || timers[i].Span == TimeSpan.MinValue)
\r
235 label.Visible = false;
\r
236 shipLabels.Hp.ForeColor = Control.DefaultForeColor;
\r
239 var timer = timers[i];
\r
240 var ship = ships[i];
\r
241 label.Visible = true;
\r
242 label.Text = timer.Span.ToString(@"mm\:ss");
\r
243 label.ForeColor = Control.DefaultForeColor;
\r
244 shipLabels.Name.SetName(ship, ShipNameWidth.AkashiTimer);
\r
245 if (timer.Diff == 0)
\r
247 shipLabels.Hp.ForeColor = Control.DefaultForeColor;
\r
252 label.ForeColor = CUDColors.Red;
\r
253 shipLabels.Hp.SetHp(ship.NowHp + timer.Diff, ship.MaxHp);
\r
254 shipLabels.Hp.ForeColor = Color.DimGray;
\r
256 AdjustAkashiTimer(label, shipLabels.Hp);
\r
260 private void AdjustAkashiTimer(Control timer, Control hp)
\r
262 if (_originalLeft == 0)
\r
263 _originalLeft = timer.Left;
\r
264 const int labelMargin = 3;
\r
265 var overlap = timer.Right - hp.Left - labelMargin;
\r
266 timer.Left = overlap < 0 ? _originalLeft : timer.Left - overlap;
\r
269 private static int ShortestSpanIndex(AkashiTimer.RepairSpan[] timers)
\r
271 var index = -1; // Spanが全部MinValueかZeroなら-1
\r
272 for (var i = 0; i < timers.Length; i++)
\r
274 if (timers[i].Span <= TimeSpan.Zero)
\r
276 if (index == -1 || timers[i].Span < timers[index].Span)
\r
283 private class CombinedShipLines
\r
285 private readonly ShipLabels[] _combinedLines = new ShipLabels[ShipInfo.MemberCount * 2];
\r
287 private const int Top = 1;
\r
288 private const int LineHeight = 16;
\r
290 public void Create(Control parent, HpToggle hpToggle, EventHandler onClick)
\r
292 parent.SuspendLayout();
\r
293 CreateHeader(parent, hpToggle);
\r
294 for (var i = 0; i < _combinedLines.Length; i++)
\r
296 var x = PanelWidth / 2 * (i / ShipInfo.MemberCount);
\r
297 var y = Top + LineHeight * (i % ShipInfo.MemberCount + 1);
\r
298 var labels = _combinedLines[i] = new ShipLabels
\r
300 Name = new ShipLabel.Name(new Point(x + 2, y + 2), ShipNameWidth.Combined),
\r
301 Hp = new ShipLabel.Hp(new Point(x + 88, y), LineHeight),
\r
302 Cond = new ShipLabel.Cond(new Point(x + 85, y), LineHeight),
\r
303 BackGround = new Label {Location = new Point(x, y), Size = new Size(PanelWidth / 2, LineHeight)}
\r
305 labels.Arrange(parent, CustomColors.ColumnColors.DarkFirst(i));
\r
306 labels.SetClickHandler(onClick);
\r
308 var hpLabel = _combinedLines[i].Hp;
\r
309 hpToggle.AddHpLabel(hpLabel);
\r
311 parent.ResumeLayout();
\r
314 private void CreateHeader(Control parent, HpToggle hpToggle)
\r
316 var headings = new Control[]
\r
318 new Label {Location = new Point(68, Top), Text = "HP", AutoSize = true},
\r
319 new Label {Location = new Point(86, Top), Text = "cnd", AutoSize = true},
\r
320 new Label {Location = new Point(177, Top), Text = "HP", AutoSize = true},
\r
321 new Label {Location = new Point(195, Top), Text = "cnd", AutoSize = true},
\r
322 new Label {Location = new Point(0, 1), Size = new Size(PanelWidth, LineHeight - 1)}
\r
324 parent.Controls.AddRange(headings);
\r
325 foreach (var control in headings)
\r
327 Scaler.Scale(control);
\r
328 control.BackColor = CustomColors.ColumnColors.Bright;
\r
330 headings[0].Cursor = headings[2].Cursor = Cursors.Hand;
\r
331 hpToggle.SetClickHandler(headings[0]);
\r
332 hpToggle.SetClickHandler(headings[2]);
\r
335 public void Set(IReadOnlyList<ShipStatus> first, IReadOnlyList<ShipStatus> second)
\r
337 for (var i = 0; i < _combinedLines.Length; i++)
\r
339 var idx = i % ShipInfo.MemberCount;
\r
340 var ships = i < ShipInfo.MemberCount ? first : second;
\r
341 var labels = _combinedLines[i];
\r
342 if (idx >= ships.Count)
\r
347 labels.Set(ships[idx]);
\r