OSDN Git Service

一覧をスクロールさせる動作をListScrollerに分離する
authorKazuhiro Fujieda <fujieda@users.osdn.me>
Mon, 22 Apr 2019 13:04:00 +0000 (22:04 +0900)
committerKazuhiro Fujieda <fujieda@users.osdn.me>
Sun, 28 Apr 2019 07:48:39 +0000 (16:48 +0900)
KancolleSniffer.sln.DotSettings
KancolleSniffer/KancolleSniffer.csproj
KancolleSniffer/View/ListScroller.cs [new file with mode: 0644]
KancolleSniffer/View/QuestPanel.cs
KancolleSniffer/View/RepairListForMain.cs

index 91ca9f0..e5c4fb3 100644 (file)
@@ -45,6 +45,7 @@
        <s:Boolean x:Key="/Default/UserDictionary/Words/=Nyukyo/@EntryIndexedValue">True</s:Boolean>
        <s:Boolean x:Key="/Default/UserDictionary/Words/=Pushbullet/@EntryIndexedValue">True</s:Boolean>
        <s:Boolean x:Key="/Default/UserDictionary/Words/=Ryusei/@EntryIndexedValue">True</s:Boolean>
+       <s:Boolean x:Key="/Default/UserDictionary/Words/=Scroller/@EntryIndexedValue">True</s:Boolean>
        <s:Boolean x:Key="/Default/UserDictionary/Words/=Scrollify/@EntryIndexedValue">True</s:Boolean>
        <s:Boolean x:Key="/Default/UserDictionary/Words/=Seiran/@EntryIndexedValue">True</s:Boolean>
        <s:Boolean x:Key="/Default/UserDictionary/Words/=taiha/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
index fcc6bf2..2a13202 100644 (file)
     </Compile>\r
     <Compile Include="Net\HttpProxy.cs" />\r
     <Compile Include="Util\HttpUtility.cs" />\r
+    <Compile Include="View\ListScroller.cs" />\r
     <Compile Include="View\NumberAndHistory.cs" />\r
     <Compile Include="View\ItemTreeView.cs">\r
       <SubType>Component</SubType>\r
diff --git a/KancolleSniffer/View/ListScroller.cs b/KancolleSniffer/View/ListScroller.cs
new file mode 100644 (file)
index 0000000..d5fab2a
--- /dev/null
@@ -0,0 +1,119 @@
+// Copyright (C) 2019 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//    http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+using System;\r
+using System.Drawing;\r
+using System.Windows.Forms;\r
+\r
+namespace KancolleSniffer.View\r
+{\r
+    public class ListScroller\r
+    {\r
+        private readonly Panel _panel;\r
+\r
+        public int Padding { get; set; }\r
+\r
+        public int Position { get; set; }\r
+\r
+        public int Lines { get; set; }\r
+\r
+        public int DataCount { get; set; }\r
+\r
+        public event Action Update;\r
+\r
+        public ListScroller(Panel panel, Label[] topLabels, Label[] bottomLabels)\r
+        {\r
+            _panel = panel;\r
+            panel.Paint += (obj, ev) => DrawMark();\r
+            SetTopEventHandler(topLabels);\r
+            SetBottomEventHandler(bottomLabels);\r
+        }\r
+\r
+        public void SetTopEventHandler(Label[] top)\r
+        {\r
+            foreach (var label in top)\r
+            {\r
+                label.MouseEnter += TopLineOnMouseEnter;\r
+                label.MouseLeave += TopLineOnMouseLeave;\r
+            }\r
+            _topScrollRepeatTimer.Tick += TopLineOnMouseEnter;\r
+        }\r
+\r
+        public void SetBottomEventHandler(Label[] bottom)\r
+        {\r
+            foreach (var label in bottom)\r
+            {\r
+                label.MouseEnter += BottomLineOnMouseEnter;\r
+                label.MouseLeave += BottomLineOnMouseLeave;\r
+            }\r
+            _bottomScrollRepeatTimer.Tick += BottomLineOnMouseEnter;\r
+        }\r
+\r
+        private readonly Timer _topScrollRepeatTimer = new Timer {Interval = 100};\r
+        private readonly Timer _bottomScrollRepeatTimer = new Timer {Interval = 100};\r
+\r
+        private void TopLineOnMouseEnter(object sender, EventArgs e)\r
+        {\r
+            if (Position == 0)\r
+                return;\r
+            Position--;\r
+            Update?.Invoke();\r
+            _topScrollRepeatTimer.Start();\r
+        }\r
+\r
+        private void TopLineOnMouseLeave(object sender, EventArgs e)\r
+        {\r
+            _topScrollRepeatTimer.Stop();\r
+        }\r
+\r
+        private void BottomLineOnMouseEnter(object sender, EventArgs e)\r
+        {\r
+            if (Position + Lines >= DataCount)\r
+                return;\r
+            Position++;\r
+            Update?.Invoke();\r
+            _bottomScrollRepeatTimer.Start();\r
+        }\r
+\r
+        private void BottomLineOnMouseLeave(object sender, EventArgs e)\r
+        {\r
+            _bottomScrollRepeatTimer.Stop();\r
+        }\r
+\r
+        public void DrawMark()\r
+        {\r
+            using (var g = _panel.CreateGraphics())\r
+            {\r
+                var topBrush = Position > 0 ? Brushes.Black : new SolidBrush(_panel.BackColor);\r
+                g.FillPolygon(topBrush,\r
+                    new[]\r
+                    {\r
+                        new PointF(_panel.Width * 0.45f, Padding), new PointF(_panel.Width * 0.55f, Padding),\r
+                        new PointF(_panel.Width * 0.5f, 0), new PointF(_panel.Width * 0.45f, Padding)\r
+                    });\r
+                var bottomBrush = Position + Lines < DataCount\r
+                    ? Brushes.Black\r
+                    : new SolidBrush(_panel.BackColor);\r
+                g.FillPolygon(bottomBrush,\r
+                    new[]\r
+                    {\r
+                        new PointF(_panel.Width * 0.45f, _panel.Height - Padding - 2),\r
+                        new PointF(_panel.Width * 0.55f, _panel.Height - Padding - 2),\r
+                        new PointF(_panel.Width * 0.5f, _panel.Height - 2),\r
+                        new PointF(_panel.Width * 0.45f, _panel.Height - Padding - 2)\r
+                    });\r
+            }\r
+        }\r
+    }\r
+}
\ No newline at end of file
index 1f51841..dd46444 100644 (file)
@@ -31,18 +31,23 @@ namespace KancolleSniffer.View
 \r
     public class QuestPanel : PanelWithToolTip\r
     {\r
-        const int TopMargin = 5;\r
-        const int LeftMargin = 2;\r
-        const int LineHeight = 14;\r
+        private const int TopMargin = 5;\r
+        private const int LeftMargin = 2;\r
+        private const int LabelHeight = 12;\r
+        private const int LineHeight = 14;\r
         private const int Lines = 6;\r
         private readonly QuestLabels[] _labels = new QuestLabels[Lines];\r
         private QuestStatus[] _questList = new QuestStatus[0];\r
-        private int _listPosition;\r
+        private ListScroller _listScroller;\r
 \r
         public QuestPanel()\r
         {\r
-            const int height = 12;\r
+            CreateLabels();\r
+            SetupListScroller();\r
+        }\r
 \r
+        private void CreateLabels()\r
+        {\r
             SuspendLayout();\r
             for (var i = 0; i < Lines; i++)\r
             {\r
@@ -52,7 +57,7 @@ namespace KancolleSniffer.View
                     Color = new Label\r
                     {\r
                         Location = new Point(LeftMargin, y + 1),\r
-                        Size = new Size(4, height - 1)\r
+                        Size = new Size(4, LabelHeight - 1)\r
                     },\r
                     Name = new Label\r
                     {\r
@@ -68,7 +73,7 @@ namespace KancolleSniffer.View
                     Progress = new Label\r
                     {\r
                         Location = new Point(LeftMargin + 186, y),\r
-                        Size = new Size(29, height),\r
+                        Size = new Size(29, LabelHeight),\r
                         TextAlign = ContentAlignment.MiddleRight\r
                     }\r
                 };\r
@@ -77,65 +82,28 @@ namespace KancolleSniffer.View
                 Controls.AddRange(_labels[i].Labels);\r
             }\r
             ResumeLayout();\r
-            SetScrollEventHandlers();\r
         }\r
 \r
-        private void SetScrollEventHandlers()\r
+        private void SetupListScroller()\r
         {\r
-            foreach (var label in _labels[0].Labels)\r
-            {\r
-                label.MouseEnter += TopLineOnMouseEnter;\r
-                label.MouseLeave += TopLineOnMouseLeave;\r
-            }\r
-            foreach (var label in _labels[Lines - 1].Labels)\r
+            _listScroller = new ListScroller(this, _labels[0].Labels, _labels[Lines - 1].Labels)\r
             {\r
-                label.MouseEnter += BottomLineOnMouseEnter;\r
-                label.MouseLeave += BottomLineOnMouseLeave;\r
-            }\r
-            _topScrollRepeatTimer.Tick += TopLineOnMouseEnter;\r
-            _bottomScrollRepeatTimer.Tick += BottomLineOnMouseEnter;\r
-        }\r
-\r
-        private readonly Timer _topScrollRepeatTimer = new Timer {Interval = 100};\r
-        private readonly Timer _bottomScrollRepeatTimer = new Timer {Interval = 100};\r
-\r
-        private void TopLineOnMouseEnter(object sender, EventArgs e)\r
-        {\r
-            if (_listPosition == 0)\r
-                return;\r
-            _listPosition--;\r
-            ShowQuestList();\r
-            _topScrollRepeatTimer.Start();\r
-        }\r
-\r
-        private void TopLineOnMouseLeave(object sender, EventArgs e)\r
-        {\r
-            _topScrollRepeatTimer.Stop();\r
-        }\r
-\r
-        private void BottomLineOnMouseEnter(object sender, EventArgs e)\r
-        {\r
-            if (_listPosition + Lines >= _questList.Length)\r
-                return;\r
-            _listPosition++;\r
-            ShowQuestList();\r
-            _bottomScrollRepeatTimer.Start();\r
-        }\r
-\r
-        private void BottomLineOnMouseLeave(object sender, EventArgs e)\r
-        {\r
-            _bottomScrollRepeatTimer.Stop();\r
+                Lines = Lines,\r
+                Padding = TopMargin\r
+            };\r
+            _listScroller.Update += ShowQuestList;\r
         }\r
 \r
         public void Update(QuestStatus[] quests)\r
         {\r
             _questList = quests;\r
+            _listScroller.DataCount = quests.Length;\r
             if (quests.Length <= Lines)\r
-                _listPosition = 0;\r
+                _listScroller.Position = 0;\r
             ShowQuestList();\r
         }\r
 \r
-        public void ShowQuestList()\r
+        private void ShowQuestList()\r
         {\r
             SuspendLayout();\r
             for (var i = 0; i < Lines; i++)\r
@@ -147,7 +115,7 @@ namespace KancolleSniffer.View
                     ClearCount(labels.Count);\r
                     continue;\r
                 }\r
-                var quest = _questList[i + _listPosition];\r
+                var quest = _questList[i + _listScroller.Position];\r
                 SetQuest(labels, quest);\r
                 if (quest.Count.Id == 0)\r
                 {\r
@@ -157,7 +125,7 @@ namespace KancolleSniffer.View
                 SetCount(labels.Count, quest.Count);\r
             }\r
             ResumeLayout(true);\r
-            DrawMark();\r
+            _listScroller.DrawMark();\r
         }\r
 \r
         private void ClearQuest(QuestLabels labels)\r
@@ -194,35 +162,5 @@ namespace KancolleSniffer.View
         }\r
 \r
         public event EventHandler NameLabelDoubleClick;\r
-\r
-        protected override void OnPaint(PaintEventArgs e)\r
-        {\r
-            base.OnPaint(e);\r
-            DrawMark();\r
-        }\r
-\r
-        private void DrawMark()\r
-        {\r
-            using (var g = CreateGraphics())\r
-            {\r
-                var topBrush = _listPosition > 0 ? Brushes.Black : new SolidBrush(BackColor);\r
-                g.FillPolygon(topBrush,\r
-                    new[]\r
-                    {\r
-                        new PointF(Width * 0.45f, TopMargin), new PointF(Width * 0.55f, TopMargin),\r
-                        new PointF(Width * 0.5f, 0), new PointF(Width * 0.45f, TopMargin)\r
-                    });\r
-                var bottomBrush = _listPosition + Lines < _questList.Length\r
-                    ? Brushes.Black\r
-                    : new SolidBrush(BackColor);\r
-                g.FillPolygon(bottomBrush,\r
-                    new[]\r
-                    {\r
-                        new PointF(Width * 0.45f, Height - TopMargin - 2),\r
-                        new PointF(Width * 0.55f, Height - TopMargin - 2),\r
-                        new PointF(Width * 0.5f, Height - 2), new PointF(Width * 0.45f, Height - TopMargin - 2)\r
-                    });\r
-            }\r
-        }\r
     }\r
 }
\ No newline at end of file
index aeb2299..1436eb0 100644 (file)
 // limitations under the License.\r
 \r
 using System;\r
-using System.Collections;\r
-using System.Collections.Generic;\r
 using System.Drawing;\r
 using System.Linq;\r
 using System.Windows.Forms;\r
 using KancolleSniffer.Model;\r
 using static System.Math;\r
+// ReSharper disable CoVariantArrayConversion\r
 \r
 namespace KancolleSniffer.View\r
 {\r
@@ -30,9 +29,9 @@ namespace KancolleSniffer.View
         private const int LineHeight = 16;\r
         private readonly RepairListLabels[] _repairLabels = new RepairListLabels[14];\r
         private ShipStatus[] _repairList = new ShipStatus[0];\r
-        private int _repairListPosition;\r
+        private ListScroller _listScroller;\r
 \r
-        private class RepairListLabels : IEnumerable<ShipLabel>\r
+        private class RepairListLabels\r
         {\r
             public ShipLabel Fleet { get; set; }\r
             public ShipLabel Name { get; set; }\r
@@ -40,16 +39,7 @@ namespace KancolleSniffer.View
             public ShipLabel Damage { get; set; }\r
             public ShipLabel BackGround { private get; set; }\r
 \r
-            public IEnumerator<ShipLabel> GetEnumerator()\r
-            {\r
-                foreach (var label in new[] {Fleet, Damage, Time, Name, BackGround})\r
-                    yield return label;\r
-            }\r
-\r
-            IEnumerator IEnumerable.GetEnumerator()\r
-            {\r
-                return GetEnumerator();\r
-            }\r
+            public ShipLabel[] Labels => new[] {Fleet, Damage, Time, Name, BackGround};\r
         }\r
 \r
         public void CreateLabels(EventHandler onClick)\r
@@ -71,68 +61,32 @@ namespace KancolleSniffer.View
                         Size = new Size(Width, height + LabelPadding + 1)\r
                     }\r
                 };\r
-                Controls.AddRange(_repairLabels[i].Cast<Control>().ToArray());\r
-                foreach (var label in _repairLabels[i])\r
+                Controls.AddRange(_repairLabels[i].Labels);\r
+                foreach (var label in _repairLabels[i].Labels)\r
                 {\r
                     label.Scale();\r
                     label.PresetColor = label.BackColor = ShipLabel.ColumnColors[(i + 1) % 2];\r
                     label.Click += onClick;\r
                 }\r
             }\r
-            SetScrollEventHandler();\r
             ResumeLayout();\r
+            SetupListScroller();\r
         }\r
 \r
-        private void SetScrollEventHandler()\r
+        private void SetupListScroller()\r
         {\r
-            foreach (var label in _repairLabels.First())\r
+            _listScroller = new ListScroller(this, _repairLabels[0].Labels, _repairLabels.Last().Labels)\r
             {\r
-                label.MouseEnter += TopRepairLabelsOnMouseEnter;\r
-                label.MouseLeave += TopRepairLabelsOnMouseLeave;\r
-            }\r
-            foreach (var label in _repairLabels.Last())\r
-            {\r
-                label.MouseEnter += BottomRepairLabelsOnMouseEnter;\r
-                label.MouseLeave += BottomRepairLabelsOnMouseLeave;\r
-            }\r
-            _topScrollRepeatTimer.Tick += TopRepairLabelsOnMouseEnter;\r
-            _bottomScrollRepeatTimer.Tick += BottomRepairLabelsOnMouseEnter;\r
-        }\r
-\r
-        private readonly Timer _topScrollRepeatTimer = new Timer {Interval = 100};\r
-        private readonly Timer _bottomScrollRepeatTimer = new Timer {Interval = 100};\r
-\r
-        private void TopRepairLabelsOnMouseEnter(object sender, EventArgs e)\r
-        {\r
-            if (_repairListPosition == 0)\r
-                return;\r
-            _repairListPosition--;\r
-            ShowRepairList();\r
-            _topScrollRepeatTimer.Start();\r
-        }\r
-\r
-        private void TopRepairLabelsOnMouseLeave(object sender, EventArgs e)\r
-        {\r
-            _topScrollRepeatTimer.Stop();\r
-        }\r
-\r
-        private void BottomRepairLabelsOnMouseEnter(object sender, EventArgs e)\r
-        {\r
-            if (_repairListPosition + _repairLabels.Length >= _repairList.Length)\r
-                return;\r
-            _repairListPosition++;\r
-            ShowRepairList();\r
-            _bottomScrollRepeatTimer.Start();\r
-        }\r
-\r
-        private void BottomRepairLabelsOnMouseLeave(object sender, EventArgs e)\r
-        {\r
-            _bottomScrollRepeatTimer.Stop();\r
+                Lines = _repairLabels.Length,\r
+                Padding = PanelPadding\r
+            };\r
+            _listScroller.Update += ShowRepairList;\r
         }\r
 \r
         public void SetRepairList(ShipStatus[] list)\r
         {\r
             _repairList = list;\r
+            _listScroller.DataCount = list.Length;\r
             SetPanelHeight();\r
             if (list.Length == 0)\r
             {\r
@@ -142,7 +96,7 @@ namespace KancolleSniffer.View
                 _repairLabels[0].Name.SetName("なし");\r
                 return;\r
             }\r
-            _repairListPosition = Min(_repairListPosition, Max(0, _repairList.Length - _repairLabels.Length));\r
+            _listScroller.Position = Min(_listScroller.Position, Max(0, _repairList.Length - _repairLabels.Length));\r
             ShowRepairList();\r
         }\r
 \r
@@ -153,11 +107,11 @@ namespace KancolleSniffer.View
                 (int)Round(ShipLabel.ScaleFactor.Height * lines * LineHeight + PanelPadding * 2));\r
         }\r
 \r
-        public void ShowRepairList()\r
+        private void ShowRepairList()\r
         {\r
             for (var i = 0; i < Min(_repairList.Length, _repairLabels.Length); i++)\r
             {\r
-                var s = _repairList[i + _repairListPosition];\r
+                var s = _repairList[i + _listScroller.Position];\r
                 var labels = _repairLabels[i];\r
                 labels.Fleet.SetFleet(s);\r
                 labels.Name.SetName(s, ShipNameWidth.RepairList);\r
@@ -166,10 +120,10 @@ namespace KancolleSniffer.View
             }\r
             if (_repairList.Length < _repairLabels.Length)\r
                 ClearLabels(_repairList.Length);\r
-            DrawMark();\r
+            _listScroller.DrawMark();\r
         }\r
 \r
-        public void ClearLabels(int i)\r
+        private void ClearLabels(int i)\r
         {\r
             var labels = _repairLabels[i];\r
             labels.Fleet.Text = "";\r
@@ -177,35 +131,5 @@ namespace KancolleSniffer.View
             labels.Time.Text = "";\r
             labels.Damage.BackColor = labels.Damage.PresetColor;\r
         }\r
-\r
-        private void DrawMark()\r
-        {\r
-            using (var g = CreateGraphics())\r
-            {\r
-                var topBrush = _repairListPosition > 0 ? Brushes.Black : new SolidBrush(BackColor);\r
-                g.FillPolygon(topBrush,\r
-                    new[]\r
-                    {\r
-                        new PointF(Width * 0.45f, PanelPadding), new PointF(Width * 0.55f, PanelPadding),\r
-                        new PointF(Width * 0.5f, 0), new PointF(Width * 0.45f, PanelPadding)\r
-                    });\r
-                var bottomBrush = _repairLabels.Length + _repairListPosition < _repairList.Length\r
-                    ? Brushes.Black\r
-                    : new SolidBrush(BackColor);\r
-                g.FillPolygon(bottomBrush,\r
-                    new[]\r
-                    {\r
-                        new PointF(Width * 0.45f, Height - PanelPadding - 2),\r
-                        new PointF(Width * 0.55f, Height - PanelPadding - 2),\r
-                        new PointF(Width * 0.5f, Height - 2), new PointF(Width * 0.45f, Height - PanelPadding - 2)\r
-                    });\r
-            }\r
-        }\r
-\r
-        protected override void OnPaint(PaintEventArgs e)\r
-        {\r
-            base.OnPaint(e);\r
-            DrawMark();\r
-        }\r
     }\r
 }
\ No newline at end of file