OSDN Git Service

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