1 // Copyright (C) 2019 Kazuhiro Fujieda <fujieda@users.osdn.me>
\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
7 // http://www.apache.org/licenses/LICENSE-2.0
\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
16 using System.Drawing;
\r
18 using System.Windows.Forms;
\r
19 using KancolleSniffer.Model;
\r
21 // ReSharper disable CoVariantArrayConversion
\r
23 namespace KancolleSniffer.View
\r
25 public class QuestLabels
\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
32 public ShipLabel[] Labels => new[] {Color, Count, Progress, Name};
\r
35 public class QuestPanel : PanelWithToolTip
\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
47 public void CreateLabels(int lines, EventHandler onDoubleClick)
\r
49 _lines = LimitLines(lines);
\r
50 _labels = new QuestLabels[_lines];
\r
52 Height = Scaler.ScaleHeight(TopMargin * 2 + LineHeight * lines);
\r
53 for (var i = 0; i < _lines; i++)
\r
55 var y = TopMargin + i * LineHeight;
\r
56 _labels[i] = new QuestLabels
\r
58 Color = new ShipLabel
\r
60 Location = new Point(LeftMargin, y + 1),
\r
61 Size = new Size(4, LabelHeight - 1)
\r
63 Name = new ShipLabel
\r
65 Location = new Point(LeftMargin + 4, y),
\r
66 Size = new Size(193, LabelHeight)
\r
68 Count = new ShipLabel
\r
70 Location = new Point(LeftMargin + 189, y),
\r
74 Progress = new ShipLabel
\r
76 Location = new Point(LeftMargin + 186, y),
\r
77 Size = new Size(29, LabelHeight),
\r
78 TextAlign = ContentAlignment.MiddleRight
\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
87 SetupListScroller();
\r
90 private static int LimitLines(int lines)
\r
94 return Math.Min(Math.Max(lines, min), max);
\r
97 private void SetupListScroller()
\r
99 _listScroller = new ListScroller(this, _labels[0].Labels, _labels[_lines - 1].Labels)
\r
102 Padding = TopMargin
\r
104 _listScroller.Update += ShowQuestList;
\r
105 _listScroller.StartScroll += () => { ToolTip.Active = false; };
\r
106 _listScroller.EndScroll += () => { ToolTip.Active = true; };
\r
109 public void Update(QuestStatus[] quests)
\r
111 _listScroller.DataCount = quests.Length;
\r
112 _listScroller.Position = CalcScrollPosition(quests);
\r
113 _questList = quests.Select(q => q.Clone()).ToArray();
\r
117 private int CalcScrollPosition(QuestStatus[] newQuests)
\r
119 if (newQuests.Length <= _lines)
\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
128 changedIndex = _questList.TakeWhile((q, i) => q.Id == newQuests[i].Id).Count();
\r
130 else if (newQuests.Length == _questList.Length)
\r
132 changedIndex = _questList.TakeWhile((q, i) => q.Count.Equals(newQuests[i].Count)).Count();
\r
133 if (changedIndex == _questList.Length) // unchanged
\r
136 if (changedIndex < current)
\r
137 return changedIndex;
\r
138 if (changedIndex > bottomIndex)
\r
139 return current + changedIndex - bottomIndex;
\r
143 private void ShowQuestList()
\r
146 for (var i = 0; i < _lines; i++)
\r
148 var labels = _labels[i];
\r
149 if (i >= _questList.Length)
\r
151 ClearQuest(labels);
\r
152 ClearCount(labels.Count);
\r
155 var quest = _questList[i + _listScroller.Position];
\r
156 SetQuest(labels, quest);
\r
157 if (quest.Count.Id == 0)
\r
159 ClearCount(labels.Count);
\r
162 SetCount(labels.Count, quest.Count);
\r
164 ResumeLayout(true);
\r
165 _listScroller.DrawMark();
\r
168 private void ClearQuest(QuestLabels labels)
\r
170 labels.Color.BackColor = DefaultBackColor;
\r
171 labels.Name.Text = labels.Progress.Text = "";
\r
172 ToolTip.SetToolTip(labels.Name, "");
\r
175 private void ClearCount(Label label)
\r
178 label.ForeColor = Color.Black;
\r
179 ToolTip.SetToolTip(label, "");
\r
182 private void SetQuest(QuestLabels labels, QuestStatus quest)
\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
190 private void SetCount(Label label, QuestCount count)
\r
192 label.Text = " " + count;
\r
193 label.ForeColor = count.Cleared ? CUDColors.Red : Color.Black;
\r
194 ToolTip.SetToolTip(label, count.ToToolTip());
\r