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.Drawing;\r
17 using System.Linq;\r
18 using System.Windows.Forms;\r
19 using static System.Math;\r
20 \r
21 namespace KancolleSniffer\r
22 {\r
23     public class RepairListForMain : Panel\r
24     {\r
25         private const int PanelPadding = 5;\r
26         private const int LabelPadding = 2;\r
27         private const int LineHeight = 16;\r
28         private readonly ShipLabel[][] _repairLabels = new ShipLabel[14][];\r
29         private ShipStatus[] _repairList;\r
30         private int _repairListPosition;\r
31 \r
32         public void CreateLabels(EventHandler onClick)\r
33         {\r
34             SuspendLayout();\r
35             for (var i = 0; i < _repairLabels.Length; i++)\r
36             {\r
37                 var y = PanelPadding + LabelPadding + i * LineHeight;\r
38                 const int height = 12;\r
39                 Controls.AddRange(_repairLabels[i] = new[]\r
40                 {\r
41                     new ShipLabel {Location = new Point(0, y), Size = new Size(11, height)},\r
42                     new ShipLabel {Location = new Point(119, y), Size = new Size(5, height - 1)},\r
43                     new ShipLabel {Location = new Point(75, y), AutoSize = true},\r
44                     new ShipLabel {Location = new Point(9, y), AutoSize = true},\r
45                     new ShipLabel {Location = new Point(0, y - LabelPadding), Size = new Size(Width, height + LabelPadding + 1)}\r
46                 });\r
47                 foreach (var label in _repairLabels[i])\r
48                 {\r
49                     label.Scale();\r
50                     label.PresetColor = label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
51                     label.Click += onClick;\r
52                 }\r
53             }\r
54             foreach (var label in _repairLabels[0])\r
55             {\r
56                 label.MouseEnter += TopRepairLabelsOnMouseEnter;\r
57                 label.MouseLeave += TopRepairLabelsOnMouseLeave;\r
58             }\r
59             _topScrollRepeatTimer.Tick += TopRepairLabelsOnMouseEnter;\r
60             foreach (var label in _repairLabels.Last())\r
61             {\r
62                 label.MouseEnter += BottomRepairLabelsOnMouseEnter;\r
63                 label.MouseLeave += BottomRepairLabelsOnMouseLeave;\r
64             }\r
65             _bottomScrollRepeatTimer.Tick += BottomRepairLabelsOnMouseEnter;\r
66             ResumeLayout();\r
67         }\r
68 \r
69         private readonly Timer _topScrollRepeatTimer = new Timer {Interval = 100};\r
70         private readonly Timer _bottomScrollRepeatTimer = new Timer {Interval = 100};\r
71 \r
72         private void TopRepairLabelsOnMouseEnter(object sender, EventArgs e)\r
73         {\r
74             if (_repairListPosition == 0)\r
75                 return;\r
76             _repairListPosition--;\r
77             ShowRepairList();\r
78             _topScrollRepeatTimer.Start();\r
79         }\r
80 \r
81         private void TopRepairLabelsOnMouseLeave(object sender, EventArgs e)\r
82         {\r
83             _topScrollRepeatTimer.Stop();\r
84         }\r
85 \r
86         private void BottomRepairLabelsOnMouseEnter(object sender, EventArgs e)\r
87         {\r
88             if (_repairListPosition + _repairLabels.Length >= _repairList.Length)\r
89                 return;\r
90             _repairListPosition++;\r
91             ShowRepairList();\r
92             _bottomScrollRepeatTimer.Start();\r
93         }\r
94 \r
95         private void BottomRepairLabelsOnMouseLeave(object sender, EventArgs e)\r
96         {\r
97             _bottomScrollRepeatTimer.Stop();\r
98         }\r
99 \r
100         public void SetRepairList(ShipStatus[] list)\r
101         {\r
102             const int fleet = 0, name = 3, time = 2, damage = 1;\r
103             _repairList = list;\r
104             if (list.Length == 0)\r
105             {\r
106                 Size = new Size(Width, (int)Round(ShipLabel.ScaleFactor.Height * (LineHeight + PanelPadding * 2)));\r
107                 var labels = _repairLabels[0];\r
108                 labels[fleet].Text = "";\r
109                 labels[name].SetName("なし");\r
110                 labels[time].Text = "";\r
111                 labels[damage].BackColor = labels[damage].PresetColor;\r
112                 return;\r
113             }\r
114             Size = new Size(Width,\r
115                 (int)Round(ShipLabel.ScaleFactor.Height *\r
116                            (Min(_repairList.Length, _repairLabels.Length) * LineHeight + PanelPadding * 2)));\r
117             _repairListPosition = Min(_repairListPosition, Max(0, _repairList.Length - _repairLabels.Length));\r
118             ShowRepairList();\r
119         }\r
120 \r
121         public void ShowRepairList()\r
122         {\r
123             const int fleet = 0, name = 3, time = 2, damage = 1;\r
124             for (var i = 0; i < Min(_repairList.Length, _repairLabels.Length); i++)\r
125             {\r
126                 var s = _repairList[i + _repairListPosition];\r
127                 var labels = _repairLabels[i];\r
128                 labels[fleet].SetFleet(s);\r
129                 labels[name].SetName(s, ShipNameWidth.RepairList);\r
130                 labels[time].SetRepairTime(s);\r
131                 labels[damage].BackColor = ShipLabel.DamageColor(s, labels[damage].PresetColor);\r
132             }\r
133             DrawMark();\r
134         }\r
135 \r
136         private void DrawMark()\r
137         {\r
138             using (var g = CreateGraphics())\r
139             {\r
140                 var topBrush = _repairListPosition > 0 ? Brushes.Black : new SolidBrush(BackColor);\r
141                 g.FillPolygon(topBrush,\r
142                     new[]\r
143                     {\r
144                         new PointF(Width * 0.45f, PanelPadding), new PointF(Width * 0.55f, PanelPadding),\r
145                         new PointF(Width * 0.5f, 0), new PointF(Width * 0.45f, PanelPadding)\r
146                     });\r
147                 var bottomBrush = _repairLabels.Length + _repairListPosition < _repairList.Length\r
148                     ? Brushes.Black\r
149                     : new SolidBrush(BackColor);\r
150                 g.FillPolygon(bottomBrush,\r
151                     new[]\r
152                     {\r
153                         new PointF(Width * 0.45f, Height - PanelPadding - 2), new PointF(Width * 0.55f, Height - PanelPadding - 2),\r
154                         new PointF(Width * 0.5f, Height - 2), new PointF(Width * 0.45f, Height - PanelPadding - 2)\r
155                     });\r
156 \r
157             }\r
158         }\r
159 \r
160         protected override void OnPaint(PaintEventArgs e)\r
161         {\r
162             base.OnPaint(e);\r
163             DrawMark();\r
164         }\r
165     }\r
166 }