OSDN Git Service

DPIスケーリング時に100%のサイズで表示する機能を削除する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / ShipInfoLabels.cs
1 // Copyright (C) 2014 Kazuhiro Fujieda <fujieda@users.sourceforge.jp>\r
2 // \r
3 // This program is part of KancolleSniffer.\r
4 //\r
5 // KancolleSniffer is free software: you can redistribute it and/or modify\r
6 // it under the terms of the GNU General Public License as published by\r
7 // the Free Software Foundation, either version 3 of the License, or\r
8 // (at your option) any later version.\r
9 //\r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 //\r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, see <http://www.gnu.org/licenses/>.\r
17 \r
18 using System;\r
19 using System.Drawing;\r
20 using System.Text.RegularExpressions;\r
21 using System.Windows.Forms;\r
22 \r
23 namespace KancolleSniffer\r
24 {\r
25     public class ShipInfoLabels\r
26     {\r
27         private readonly ShipLabel[][] _labels = new ShipLabel[ShipInfo.MemberCount][];\r
28         private const int LabelHpRight = 130;\r
29         private readonly Label[] _akashiTimers = new Label[ShipInfo.MemberCount];\r
30         public static Color[] ColumnColors = {SystemColors.Control, Color.FromArgb(255, 250, 250, 250)};\r
31 \r
32         public ShipInfoLabels(Control parent, EventHandler onClick)\r
33         {\r
34             CreateLabels(parent, onClick);\r
35             CreateAkashiTimers(parent);\r
36         }\r
37 \r
38         private void CreateLabels(Control parent, EventHandler onClick)\r
39         {\r
40             parent.SuspendLayout();\r
41             const int top = 3, height = 12, lh = 16;\r
42             Control[] headings =\r
43             {\r
44                 new Label {Location = new Point(101, top), Text = "耐久", AutoSize = true},\r
45                 new Label {Location = new Point(131, top), Text = "cond", AutoSize = true},\r
46                 new Label {Location = new Point(159, top), Text = "レベル", AutoSize = true},\r
47                 new Label {Location = new Point(195, top), Text = "経験値", AutoSize = true},\r
48                 new Label {Location = new Point(0, 1), Size = new Size(parent.Width, lh - 1)}\r
49             };\r
50             foreach (var label in headings)\r
51             {\r
52                 label.Scale(ShipLabel.ScaleFactor);\r
53                 label.BackColor = ColumnColors[1];\r
54             }\r
55             parent.Controls.AddRange(headings);\r
56             for (var i = 0; i < _labels.Length; i++)\r
57             {\r
58                 var y = top + lh * (i + 1);\r
59                 parent.Controls.AddRange(_labels[i] = new[]\r
60                 {\r
61                     new ShipLabel {Location = new Point(LabelHpRight, y), AutoSize = true},\r
62                     new ShipLabel\r
63                     {\r
64                         Location = new Point(136, y),\r
65                         Size = new Size(23, height),\r
66                         TextAlign = ContentAlignment.MiddleRight\r
67                     },\r
68                     new ShipLabel\r
69                     {\r
70                         Location = new Point(170, y),\r
71                         Size = new Size(23, height),\r
72                         TextAlign = ContentAlignment.MiddleRight\r
73                     },\r
74                     new ShipLabel\r
75                     {\r
76                         Location = new Point(195, y),\r
77                         Size = new Size(41, height),\r
78                         TextAlign = ContentAlignment.MiddleRight\r
79                     },\r
80                     new ShipLabel {Location = new Point(2, y), AutoSize = true}, // 名前のZ-orderを下に\r
81                     new ShipLabel {Location = new Point(0, y - 2), Size = new Size(parent.Width, lh - 1)}\r
82                 });\r
83                 _labels[i][0].SizeChanged += labelHP_SizeChanged;\r
84                 foreach (var label in _labels[i])\r
85                 {\r
86                     label.Scale(ShipLabel.ScaleFactor);\r
87                     label.PresetColor = label.BackColor = ColumnColors[i % 2];\r
88                     label.Tag = i;\r
89                     label.Click += onClick;\r
90                 }\r
91             }\r
92             parent.ResumeLayout();\r
93         }\r
94 \r
95         private void labelHP_SizeChanged(object sender, EventArgs e)\r
96         {\r
97             var label = (Label)sender;\r
98             label.Location =\r
99                 new Point((int)Math.Round(LabelHpRight * ShipLabel.ScaleFactor.Width) - label.Width, label.Top);\r
100         }\r
101 \r
102         public void SetShipInfo(ShipStatus[] statuses)\r
103         {\r
104             var empty = new ShipStatus();\r
105             for (var i = 0; i < _labels.Length; i++)\r
106             {\r
107                 var labels = _labels[i];\r
108                 var s = i < statuses.Length ? statuses[i] : empty;\r
109                 labels[0].SetHp(s);\r
110                 labels[1].SetCond(s);\r
111                 labels[2].SetLevel(s);\r
112                 labels[3].SetExpToNext(s);\r
113                 labels[4].SetName(s);\r
114             }\r
115         }\r
116 \r
117         private void CreateAkashiTimers(Control parent)\r
118         {\r
119             parent.SuspendLayout();\r
120             for (var i = 0; i < _akashiTimers.Length; i++)\r
121             {\r
122                 const int x = 56;\r
123                 var y = 20 + 16 * i;\r
124                 Label label;\r
125                 parent.Controls.Add(\r
126                     label = _akashiTimers[i] = new Label {Location = new Point(x, y), AutoSize = true, Visible = false});\r
127                 parent.Controls.SetChildIndex(label, 0);\r
128                 label.BackColor = ColumnColors[i % 2];\r
129             }\r
130             foreach (var label in _akashiTimers)\r
131                 label.Scale(ShipLabel.ScaleFactor);\r
132             parent.ResumeLayout();\r
133         }\r
134 \r
135         public void SetAkashiTimer(ShipStatus[] statuses, AkashiTimer.RepairSpan[] timers)\r
136         {\r
137             for (var i = 0; i < _akashiTimers.Length; i++)\r
138             {\r
139                 var label = _akashiTimers[i];\r
140                 var labelHp = _labels[i][0];\r
141                 if (timers == null || i >= timers.Length || timers[i].Span == TimeSpan.MinValue)\r
142                 {\r
143                     label.Visible = false;\r
144                     labelHp.ForeColor = Control.DefaultForeColor;\r
145                     continue;\r
146                 }\r
147                 var timer = timers[i];\r
148                 var stat = statuses[i];\r
149                 label.Visible = true;\r
150                 label.Text = timer.Span.ToString(@"mm\:ss");\r
151                 if (timer.Diff == 0)\r
152                 {\r
153                     labelHp.ForeColor = Control.DefaultForeColor;\r
154                     continue;\r
155                 }\r
156                 labelHp.ForeColor = Color.DimGray;\r
157                 labelHp.SetHp(stat.NowHp + timer.Diff, stat.MaxHp);\r
158             }\r
159         }\r
160     }\r
161 \r
162     [System.ComponentModel.DesignerCategory("Code")]\r
163     public class ShipLabel : Label\r
164     {\r
165         public static SizeF ScaleFactor { get; set; }\r
166         public Color PresetColor { get; set; }\r
167 \r
168         public void SetName(ShipStatus status)\r
169         {\r
170             SetName(status.Name);\r
171         }\r
172 \r
173         public void SetName(string name)\r
174         {\r
175             var lu = name != null && new Regex(@"^\p{Lu}").IsMatch(name);\r
176             var shift = (int)Math.Round(ScaleFactor.Height);\r
177             if (lu && Font.Equals(Parent.Font))\r
178             {\r
179                 Location += new Size(0, -shift);\r
180                 Font = new Font("Tahoma", 8f);\r
181             }\r
182             else if (!lu && !Font.Equals(Parent.Font))\r
183             {\r
184                 Location += new Size(0, shift);\r
185                 Font = Parent.Font;\r
186             }\r
187             Text = name;\r
188         }\r
189 \r
190         public void SetHp(ShipStatus status)\r
191         {\r
192             SetHp(status.NowHp, status.MaxHp);\r
193         }\r
194 \r
195         public void SetHp(int now, int max)\r
196         {\r
197             var colors = new[] {PresetColor, Color.FromArgb(255, 240, 240, 100), Color.Orange, Color.Red};\r
198             Text = string.Format("{0:D}/{1:D}", now, max);\r
199             BackColor = colors[(int)ShipStatus.CalcDamage(now, max)];\r
200         }\r
201 \r
202         public void SetCond(ShipStatus status)\r
203         {\r
204             if (status.Level == 0)\r
205             {\r
206                 Text = "0";\r
207                 BackColor = PresetColor;\r
208                 return;\r
209             }\r
210             var cond = status.Cond;\r
211             Text = cond.ToString("D");\r
212             BackColor = cond >= 50\r
213                 ? Color.Yellow\r
214                 : cond >= 30\r
215                     ? PresetColor\r
216                     : cond >= 20 ? Color.Orange : Color.Red;\r
217         }\r
218 \r
219         public void SetLevel(ShipStatus status)\r
220         {\r
221             Text = status.Level.ToString("D");\r
222         }\r
223 \r
224         public void SetExpToNext(ShipStatus status)\r
225         {\r
226             Text = status.ExpToNext.ToString("D");\r
227         }\r
228     }\r
229 }