OSDN Git Service

資材報告書に現在の資材を表示する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / RepairListForMain.cs
1 // Copyright (C) 2017 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;\r
17 using System.Collections.Generic;\r
18 using System.Drawing;\r
19 using System.Linq;\r
20 using System.Windows.Forms;\r
21 using static System.Math;\r
22 \r
23 namespace KancolleSniffer\r
24 {\r
25     public class RepairListForMain : Panel\r
26     {\r
27         private const int PanelPadding = 5;\r
28         private const int LabelPadding = 2;\r
29         private const int LineHeight = 16;\r
30         private readonly RepairListLabels[] _repairLabels = new RepairListLabels[14];\r
31         private ShipStatus[] _repairList = new ShipStatus[0];\r
32         private int _repairListPosition;\r
33 \r
34         private class RepairListLabels : IEnumerable<ShipLabel>\r
35         {\r
36             public ShipLabel Fleet { get; set; }\r
37             public ShipLabel Name { get; set; }\r
38             public ShipLabel Time { get; set; }\r
39             public ShipLabel Damage { get; set; }\r
40             public ShipLabel BackGround { private get; set; }\r
41 \r
42             public IEnumerator<ShipLabel> GetEnumerator()\r
43             {\r
44                 foreach (var label in new[] {Fleet, Damage, Time, Name, BackGround})\r
45                     yield return label;\r
46             }\r
47 \r
48             IEnumerator IEnumerable.GetEnumerator()\r
49             {\r
50                 return GetEnumerator();\r
51             }\r
52         }\r
53 \r
54         public void CreateLabels(EventHandler onClick)\r
55         {\r
56             SuspendLayout();\r
57             for (var i = 0; i < _repairLabels.Length; i++)\r
58             {\r
59                 var y = PanelPadding + LabelPadding + i * LineHeight;\r
60                 const int height = 12;\r
61                 _repairLabels[i] = new RepairListLabels\r
62                 {\r
63                     Fleet = new ShipLabel {Location = new Point(0, y), Size = new Size(11, height)},\r
64                     Damage = new ShipLabel {Location = new Point(119, y), Size = new Size(5, height - 1)},\r
65                     Time = new ShipLabel {Location = new Point(75, y), AutoSize = true},\r
66                     Name = new ShipLabel {Location = new Point(9, y), AutoSize = true},\r
67                     BackGround = new ShipLabel\r
68                     {\r
69                         Location = new Point(0, y - LabelPadding),\r
70                         Size = new Size(Width, height + LabelPadding + 1)\r
71                     }\r
72                 };\r
73                 Controls.AddRange(_repairLabels[i].Cast<Control>().ToArray());\r
74                 foreach (var label in _repairLabels[i])\r
75                 {\r
76                     label.Scale();\r
77                     label.PresetColor = label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
78                     label.Click += onClick;\r
79                 }\r
80             }\r
81             SetScrollEventHandler();\r
82             ResumeLayout();\r
83         }\r
84 \r
85         private void SetScrollEventHandler()\r
86         {\r
87             foreach (var label in _repairLabels.First())\r
88             {\r
89                 label.MouseEnter += TopRepairLabelsOnMouseEnter;\r
90                 label.MouseLeave += TopRepairLabelsOnMouseLeave;\r
91             }\r
92             foreach (var label in _repairLabels.Last())\r
93             {\r
94                 label.MouseEnter += BottomRepairLabelsOnMouseEnter;\r
95                 label.MouseLeave += BottomRepairLabelsOnMouseLeave;\r
96             }\r
97             _topScrollRepeatTimer.Tick += TopRepairLabelsOnMouseEnter;\r
98             _bottomScrollRepeatTimer.Tick += BottomRepairLabelsOnMouseEnter;\r
99         }\r
100 \r
101         private readonly Timer _topScrollRepeatTimer = new Timer {Interval = 100};\r
102         private readonly Timer _bottomScrollRepeatTimer = new Timer {Interval = 100};\r
103 \r
104         private void TopRepairLabelsOnMouseEnter(object sender, EventArgs e)\r
105         {\r
106             if (_repairListPosition == 0)\r
107                 return;\r
108             _repairListPosition--;\r
109             ShowRepairList();\r
110             _topScrollRepeatTimer.Start();\r
111         }\r
112 \r
113         private void TopRepairLabelsOnMouseLeave(object sender, EventArgs e)\r
114         {\r
115             _topScrollRepeatTimer.Stop();\r
116         }\r
117 \r
118         private void BottomRepairLabelsOnMouseEnter(object sender, EventArgs e)\r
119         {\r
120             if (_repairListPosition + _repairLabels.Length >= _repairList.Length)\r
121                 return;\r
122             _repairListPosition++;\r
123             ShowRepairList();\r
124             _bottomScrollRepeatTimer.Start();\r
125         }\r
126 \r
127         private void BottomRepairLabelsOnMouseLeave(object sender, EventArgs e)\r
128         {\r
129             _bottomScrollRepeatTimer.Stop();\r
130         }\r
131 \r
132         public void SetRepairList(ShipStatus[] list)\r
133         {\r
134             _repairList = list;\r
135             SetPanelHeight();\r
136             if (list.Length == 0)\r
137             {\r
138                 SetPanelHeight();\r
139                 ClearLabels(0);\r
140                 ClearLabels(1);\r
141                 _repairLabels[0].Name.SetName("なし");\r
142                 return;\r
143             }\r
144             _repairListPosition = Min(_repairListPosition, Max(0, _repairList.Length - _repairLabels.Length));\r
145             ShowRepairList();\r
146         }\r
147 \r
148         private void SetPanelHeight()\r
149         {\r
150             var lines = Min(Max(1, _repairList.Length), _repairLabels.Length);\r
151             Size = new Size(Width, (int)Round(ShipLabel.ScaleFactor.Height * lines * LineHeight + PanelPadding * 2));\r
152         }\r
153 \r
154         public void ShowRepairList()\r
155         {\r
156             for (var i = 0; i < Min(_repairList.Length, _repairLabels.Length); i++)\r
157             {\r
158                 var s = _repairList[i + _repairListPosition];\r
159                 var labels = _repairLabels[i];\r
160                 labels.Fleet.SetFleet(s);\r
161                 labels.Name.SetName(s, ShipNameWidth.RepairList);\r
162                 labels.Time.SetRepairTime(s);\r
163                 labels.Damage.BackColor = ShipLabel.DamageColor(s, labels.Damage.PresetColor);\r
164             }\r
165             if (_repairList.Length < _repairLabels.Length)\r
166                 ClearLabels(_repairList.Length);\r
167             DrawMark();\r
168         }\r
169 \r
170         public void ClearLabels(int i)\r
171         {\r
172             var labels = _repairLabels[i];\r
173             labels.Fleet.Text = "";\r
174             labels.Name.SetName("");\r
175             labels.Time.Text = "";\r
176             labels.Damage.BackColor = labels.Damage.PresetColor;\r
177         }\r
178 \r
179         private void DrawMark()\r
180         {\r
181             using (var g = CreateGraphics())\r
182             {\r
183                 var topBrush = _repairListPosition > 0 ? Brushes.Black : new SolidBrush(BackColor);\r
184                 g.FillPolygon(topBrush,\r
185                     new[]\r
186                     {\r
187                         new PointF(Width * 0.45f, PanelPadding), new PointF(Width * 0.55f, PanelPadding),\r
188                         new PointF(Width * 0.5f, 0), new PointF(Width * 0.45f, PanelPadding)\r
189                     });\r
190                 var bottomBrush = _repairLabels.Length + _repairListPosition < _repairList.Length\r
191                     ? Brushes.Black\r
192                     : new SolidBrush(BackColor);\r
193                 g.FillPolygon(bottomBrush,\r
194                     new[]\r
195                     {\r
196                         new PointF(Width * 0.45f, Height - PanelPadding - 2), new PointF(Width * 0.55f, Height - PanelPadding - 2),\r
197                         new PointF(Width * 0.5f, Height - 2), new PointF(Width * 0.45f, Height - PanelPadding - 2)\r
198                     });\r
199             }\r
200         }\r
201 \r
202         protected override void OnPaint(PaintEventArgs e)\r
203         {\r
204             base.OnPaint(e);\r
205             DrawMark();\r
206         }\r
207     }\r
208 }