OSDN Git Service

PresetColorを廃止する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / View / QuestPanel.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.Linq;\r
18 using System.Windows.Forms;\r
19 using KancolleSniffer.Model;\r
20 \r
21 // ReSharper disable CoVariantArrayConversion\r
22 \r
23 namespace KancolleSniffer.View\r
24 {\r
25     public class QuestLabels\r
26     {\r
27         public ShipLabel Color { get; set; }\r
28         public ShipLabel Name { get; set; }\r
29         public ShipLabel Count { get; set; }\r
30         public ShipLabel Progress { get; set; }\r
31 \r
32         public ShipLabel[] Labels => new[] {Color, Count, Progress, Name};\r
33     }\r
34 \r
35     public class QuestPanel : PanelWithToolTip\r
36     {\r
37         private const int TopMargin = 5;\r
38         private const int LeftMargin = 2;\r
39         private const int LabelHeight = 12;\r
40         public const int LineHeight = 14;\r
41         private QuestLabels[] _labels;\r
42         private QuestStatus[] _questList = new QuestStatus[0];\r
43         private ListScroller _listScroller;\r
44         private int _lines;\r
45 \r
46 \r
47         public void CreateLabels(int lines, EventHandler onDoubleClick)\r
48         {\r
49             _lines = LimitLines(lines);\r
50             _labels = new QuestLabels[_lines];\r
51             SuspendLayout();\r
52             Height = Scaler.ScaleHeight(TopMargin * 2 + LineHeight * lines);\r
53             for (var i = 0; i < _lines; i++)\r
54             {\r
55                 var y = TopMargin + i * LineHeight;\r
56                 _labels[i] = new QuestLabels\r
57                 {\r
58                     Color = new ShipLabel\r
59                     {\r
60                         Location = new Point(LeftMargin, y + 1),\r
61                         Size = new Size(4, LabelHeight - 1)\r
62                     },\r
63                     Name = new ShipLabel\r
64                     {\r
65                         Location = new Point(LeftMargin + 4, y),\r
66                         Size = new Size(193, LabelHeight)\r
67                     },\r
68                     Count = new ShipLabel\r
69                     {\r
70                         Location = new Point(LeftMargin + 189, y),\r
71                         AutoSize = true,\r
72                         AnchorRight = true\r
73                     },\r
74                     Progress = new ShipLabel\r
75                     {\r
76                         Location = new Point(LeftMargin + 186, y),\r
77                         Size = new Size(29, LabelHeight),\r
78                         TextAlign = ContentAlignment.MiddleRight\r
79                     }\r
80                 };\r
81                 _labels[i].Name.DoubleClick += onDoubleClick;\r
82                 Controls.AddRange(_labels[i].Labels);\r
83                 foreach (var label in _labels[i].Labels)\r
84                     Scaler.Scale(label);\r
85             }\r
86             ResumeLayout();\r
87             SetupListScroller();\r
88         }\r
89 \r
90         private static int LimitLines(int lines)\r
91         {\r
92             const int min = 4;\r
93             const int max = 7;\r
94             return Math.Min(Math.Max(lines, min), max);\r
95         }\r
96 \r
97         private void SetupListScroller()\r
98         {\r
99             _listScroller = new ListScroller(this, _labels[0].Labels, _labels[_lines - 1].Labels)\r
100             {\r
101                 Lines = _lines,\r
102                 Padding = TopMargin\r
103             };\r
104             _listScroller.Update += ShowQuestList;\r
105             _listScroller.StartScroll += () => { ToolTip.Active = false; };\r
106             _listScroller.EndScroll += () => { ToolTip.Active = true; };\r
107         }\r
108 \r
109         public void Update(QuestStatus[] quests)\r
110         {\r
111             _listScroller.DataCount = quests.Length;\r
112             _listScroller.Position = CalcScrollPosition(quests);\r
113             _questList = quests.Select(q => q.Clone()).ToArray();\r
114             ShowQuestList();\r
115         }\r
116 \r
117         private int CalcScrollPosition(QuestStatus[] newQuests)\r
118         {\r
119             if (newQuests.Length <= _lines)\r
120                 return 0;\r
121             var current = _listScroller.Position;\r
122             var bottomIndex = current + _lines - 1;\r
123             if (newQuests.Length < _questList.Length)\r
124                 return bottomIndex >= newQuests.Length ? newQuests.Length - _lines : current;\r
125             var changedIndex = 0;\r
126             if (newQuests.Length > _questList.Length)\r
127             {\r
128                 changedIndex = _questList.TakeWhile((q, i) => q.Id == newQuests[i].Id).Count();\r
129             }\r
130             else if (newQuests.Length == _questList.Length)\r
131             {\r
132                 changedIndex = _questList.TakeWhile((q, i) => q.Count.Equals(newQuests[i].Count)).Count();\r
133                 if (changedIndex == _questList.Length) // unchanged\r
134                     return current;\r
135             }\r
136             if (changedIndex < current)\r
137                 return changedIndex;\r
138             if (changedIndex > bottomIndex)\r
139                 return current + changedIndex - bottomIndex;\r
140             return current;\r
141         }\r
142 \r
143         private void ShowQuestList()\r
144         {\r
145             SuspendLayout();\r
146             for (var i = 0; i < _lines; i++)\r
147             {\r
148                 var labels = _labels[i];\r
149                 if (i >= _questList.Length)\r
150                 {\r
151                     ClearQuest(labels);\r
152                     ClearCount(labels.Count);\r
153                     continue;\r
154                 }\r
155                 var quest = _questList[i + _listScroller.Position];\r
156                 SetQuest(labels, quest);\r
157                 if (quest.Count.Id == 0)\r
158                 {\r
159                     ClearCount(labels.Count);\r
160                     continue;\r
161                 }\r
162                 SetCount(labels.Count, quest.Count);\r
163             }\r
164             ResumeLayout(true);\r
165             _listScroller.DrawMark();\r
166         }\r
167 \r
168         private void ClearQuest(QuestLabels labels)\r
169         {\r
170             labels.Color.BackColor = DefaultBackColor;\r
171             labels.Name.Text = labels.Progress.Text = "";\r
172             ToolTip.SetToolTip(labels.Name, "");\r
173         }\r
174 \r
175         private void ClearCount(Label label)\r
176         {\r
177             label.Text = "";\r
178             label.ForeColor = Color.Black;\r
179             ToolTip.SetToolTip(label, "");\r
180         }\r
181 \r
182         private void SetQuest(QuestLabels labels, QuestStatus quest)\r
183         {\r
184             labels.Color.BackColor = quest.Color;\r
185             labels.Name.Text = quest.Name;\r
186             labels.Progress.Text = $"{quest.Progress:D}%";\r
187             ToolTip.SetToolTip(labels.Name, quest.ToToolTip());\r
188         }\r
189 \r
190         private void SetCount(Label label, QuestCount count)\r
191         {\r
192             label.Text = " " + count;\r
193             label.ForeColor = count.Cleared ? CUDColors.Red : Color.Black;\r
194             ToolTip.SetToolTip(label, count.ToToolTip());\r
195         }\r
196     }\r
197 }