OSDN Git Service

メインの要修復一覧の行間を1px詰める
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / View / ListScroller.cs
1 // Copyright (C) 2019 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.Windows.Forms;\r
18 \r
19 namespace KancolleSniffer.View\r
20 {\r
21     public class ListScroller\r
22     {\r
23         private readonly Panel _panel;\r
24 \r
25         public int Padding { get; set; }\r
26 \r
27         public int Position { get; set; }\r
28 \r
29         public int Lines { get; set; }\r
30 \r
31         public int DataCount { get; set; }\r
32 \r
33         public event Action Update;\r
34 \r
35         public ListScroller(Panel panel, Label[] topLabels, Label[] bottomLabels)\r
36         {\r
37             _panel = panel;\r
38             panel.Paint += (obj, ev) => DrawMark();\r
39             SetTopEventHandler(topLabels);\r
40             SetBottomEventHandler(bottomLabels);\r
41         }\r
42 \r
43         public void SetTopEventHandler(Label[] top)\r
44         {\r
45             foreach (var label in top)\r
46             {\r
47                 label.MouseEnter += TopLineOnMouseEnter;\r
48                 label.MouseLeave += TopLineOnMouseLeave;\r
49             }\r
50             _topScrollRepeatTimer.Tick += TopLineOnMouseEnter;\r
51         }\r
52 \r
53         public void SetBottomEventHandler(Label[] bottom)\r
54         {\r
55             foreach (var label in bottom)\r
56             {\r
57                 label.MouseEnter += BottomLineOnMouseEnter;\r
58                 label.MouseLeave += BottomLineOnMouseLeave;\r
59             }\r
60             _bottomScrollRepeatTimer.Tick += BottomLineOnMouseEnter;\r
61         }\r
62 \r
63         private readonly Timer _topScrollRepeatTimer = new Timer {Interval = 100};\r
64         private readonly Timer _bottomScrollRepeatTimer = new Timer {Interval = 100};\r
65 \r
66         private void TopLineOnMouseEnter(object sender, EventArgs e)\r
67         {\r
68             if (Position == 0)\r
69                 return;\r
70             Position--;\r
71             Update?.Invoke();\r
72             _topScrollRepeatTimer.Start();\r
73         }\r
74 \r
75         private void TopLineOnMouseLeave(object sender, EventArgs e)\r
76         {\r
77             _topScrollRepeatTimer.Stop();\r
78         }\r
79 \r
80         private void BottomLineOnMouseEnter(object sender, EventArgs e)\r
81         {\r
82             if (Position + Lines >= DataCount)\r
83                 return;\r
84             Position++;\r
85             Update?.Invoke();\r
86             _bottomScrollRepeatTimer.Start();\r
87         }\r
88 \r
89         private void BottomLineOnMouseLeave(object sender, EventArgs e)\r
90         {\r
91             _bottomScrollRepeatTimer.Stop();\r
92         }\r
93 \r
94         public void DrawMark()\r
95         {\r
96             using (var g = _panel.CreateGraphics())\r
97             {\r
98                 var topBrush = Position > 0 ? Brushes.Black : new SolidBrush(_panel.BackColor);\r
99                 g.FillPolygon(topBrush,\r
100                     new[]\r
101                     {\r
102                         new PointF(_panel.Width * 0.45f, Padding), new PointF(_panel.Width * 0.55f, Padding),\r
103                         new PointF(_panel.Width * 0.5f, 0), new PointF(_panel.Width * 0.45f, Padding)\r
104                     });\r
105                 var bottomBrush = Position + Lines < DataCount\r
106                     ? Brushes.Black\r
107                     : new SolidBrush(_panel.BackColor);\r
108                 g.FillPolygon(bottomBrush,\r
109                     new[]\r
110                     {\r
111                         new PointF(_panel.Width * 0.45f, _panel.Height - Padding - 2),\r
112                         new PointF(_panel.Width * 0.55f, _panel.Height - Padding - 2),\r
113                         new PointF(_panel.Width * 0.5f, _panel.Height - 2),\r
114                         new PointF(_panel.Width * 0.45f, _panel.Height - Padding - 2)\r
115                     });\r
116             }\r
117         }\r
118     }\r
119 }