OSDN Git Service

艦娘一覧の処理をShipListPanelとして分離する
authorKazuhiro Fujieda <fujieda@users.osdn.me>
Fri, 16 Dec 2016 12:51:15 +0000 (21:51 +0900)
committerKazuhiro Fujieda <fujieda@users.osdn.me>
Sun, 18 Dec 2016 11:34:36 +0000 (20:34 +0900)
KancolleSniffer/KancolleSniffer.csproj
KancolleSniffer/ListForm.Designer.cs
KancolleSniffer/ListForm.cs
KancolleSniffer/ShipListPanel.cs [new file with mode: 0644]

index 834acf2..f534d6f 100644 (file)
     <Compile Include="QuestInfo.cs" />\r
     <Compile Include="ConditionTimer.cs" />\r
     <Compile Include="ShipInfo.cs" />\r
+    <Compile Include="ShipListPanel.cs">\r
+      <SubType>Component</SubType>\r
+    </Compile>\r
     <Compile Include="ShipMaster.cs" />\r
     <Compile Include="Sniffer.cs" />\r
     <Compile Include="ItemInfo.cs" />\r
index daf6b47..4423781 100644 (file)
@@ -44,7 +44,7 @@ namespace KancolleSniffer
         {\r
             this.components = new System.ComponentModel.Container();\r
             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ListForm));\r
-            this.panelShipList = new System.Windows.Forms.Panel();\r
+            this.shipListPanel = new KancolleSniffer.ShipListPanel();\r
             this.contextMenuStripShipList = new System.Windows.Forms.ContextMenuStrip(this.components);\r
             this.csvToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\r
             this.kantaiSarashiToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\r
@@ -81,17 +81,17 @@ namespace KancolleSniffer
             this.contextMenuStripFleetData.SuspendLayout();\r
             this.SuspendLayout();\r
             // \r
-            // panelShipList\r
+            // shipListPanel\r
             // \r
-            this.panelShipList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \r
+            this.shipListPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \r
             | System.Windows.Forms.AnchorStyles.Left)));\r
-            this.panelShipList.AutoScroll = true;\r
-            this.panelShipList.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;\r
-            this.panelShipList.ContextMenuStrip = this.contextMenuStripShipList;\r
-            this.panelShipList.Location = new System.Drawing.Point(6, 23);\r
-            this.panelShipList.Name = "panelShipList";\r
-            this.panelShipList.Size = new System.Drawing.Size(238, 263);\r
-            this.panelShipList.TabIndex = 0;\r
+            this.shipListPanel.AutoScroll = true;\r
+            this.shipListPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;\r
+            this.shipListPanel.ContextMenuStrip = this.contextMenuStripShipList;\r
+            this.shipListPanel.Location = new System.Drawing.Point(6, 23);\r
+            this.shipListPanel.Name = "shipListPanel";\r
+            this.shipListPanel.Size = new System.Drawing.Size(238, 263);\r
+            this.shipListPanel.TabIndex = 0;\r
             // \r
             // contextMenuStripShipList\r
             // \r
@@ -386,7 +386,7 @@ namespace KancolleSniffer
             this.Controls.Add(this.richTextBoxMiscText);\r
             this.Controls.Add(this.equipPanel);\r
             this.Controls.Add(this.itemTreeView);\r
-            this.Controls.Add(this.panelShipList);\r
+            this.Controls.Add(this.shipListPanel);\r
             this.Controls.Add(this.comboBoxGroup);\r
             this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));\r
             this.KeyPreview = true;\r
@@ -410,7 +410,7 @@ namespace KancolleSniffer
 \r
         #endregion\r
 \r
-        private System.Windows.Forms.Panel panelShipList;\r
+        private ShipListPanel shipListPanel;\r
         private System.Windows.Forms.Label label1;\r
         private System.Windows.Forms.Label labelHeaderCond;\r
         private System.Windows.Forms.Label labelHeaderExp;\r
index 41f4dfb..56ec698 100644 (file)
@@ -25,19 +25,7 @@ namespace KancolleSniffer
     {\r
         private readonly Sniffer _sniffer;\r
         private readonly Config _config;\r
-        private const int LabelHeight = 12;\r
-        private const int LineHeight = 16;\r
         public const int PanelWidth = 217;\r
-        private ShipStatus[] _shipList;\r
-        private readonly List<ShipLabel[]> _labelList = new List<ShipLabel[]>();\r
-        private readonly List<Panel> _labelPanelList = new List<Panel>();\r
-        private readonly List<CheckBox[]> _checkBoxesList = new List<CheckBox[]>();\r
-        private readonly List<ShipLabel[]> _configLabelList = new List<ShipLabel[]>();\r
-        private readonly List<Panel> _checkBoxPanelList = new List<Panel>();\r
-        private readonly List<ShipLabel[]> _repairLabelList = new List<ShipLabel[]>();\r
-        private readonly List<Panel> _repairPanelList = new List<Panel>();\r
-        public const int GroupCount = 4;\r
-        private readonly HashSet<int>[] _groupSettings = new HashSet<int>[GroupCount];\r
 \r
         public enum SortOrder\r
         {\r
@@ -53,7 +41,7 @@ namespace KancolleSniffer
             _sniffer = sniffer;\r
             _config = config;\r
             var swipe = new SwipeScrollify();\r
-            swipe.AddPanel(panelShipList);\r
+            swipe.AddPanel(shipListPanel);\r
             swipe.AddTreeView(itemTreeView);\r
             swipe.AddPanel(equipPanel);\r
         }\r
@@ -64,7 +52,7 @@ namespace KancolleSniffer
             panelGroupHeader.Visible = InGroupConfig;\r
             panelRepairHeader.Visible = InRepairList;\r
             // SwipeScrollifyが誤作動するのでEnabledも切り替える\r
-            panelShipList.Visible = panelShipList.Enabled = InShipStatus || InGroupConfig || InRepairList;\r
+            shipListPanel.Visible = shipListPanel.Enabled = InShipStatus || InGroupConfig || InRepairList;\r
             itemTreeView.Visible = itemTreeView.Enabled = InItemList;\r
             equipPanel.Visible = equipPanel.Enabled = InEquip;\r
             richTextBoxMiscText.Visible = InMiscText;\r
@@ -83,9 +71,7 @@ namespace KancolleSniffer
             else\r
             {\r
                 SetHeaderSortOrder();\r
-                CreateShipList();\r
-                CreateListLabels();\r
-                SetShipLabels();\r
+                shipListPanel.Update(_sniffer, comboBoxGroup.Text, _config.ShipList.SortOrder, _config.ShipList.ShipType);\r
             }\r
         }\r
 \r
@@ -108,339 +94,6 @@ namespace KancolleSniffer
             }\r
         }\r
 \r
-        private void CreateShipList()\r
-        {\r
-            var ships = InRepairList ? _sniffer.RepairList : FilterByGroup(_sniffer.ShipList).ToArray();\r
-            var order = InRepairList ? SortOrder.Repair : _config.ShipList.SortOrder;\r
-            if (!_config.ShipList.ShipType)\r
-            {\r
-                _shipList = ships.OrderBy(s => s, new CompareShip(false, order)).ToArray();\r
-                return;\r
-            }\r
-            var types = ships.Select(s => new {Id = s.Spec.ShipType, Name = s.Spec.ShipTypeName}).Distinct().\r
-                Select(stype =>\r
-                    new ShipStatus\r
-                    {\r
-                        Spec = new ShipSpec {Name = stype.Name, ShipType = stype.Id},\r
-                        Level = 1000,\r
-                        NowHp = -1000,\r
-                        Cond = -1000\r
-                    });\r
-            _shipList = ships.Concat(types).OrderBy(s => s, new CompareShip(true, order)).ToArray();\r
-        }\r
-\r
-        private IEnumerable<ShipStatus> FilterByGroup(IEnumerable<ShipStatus> ships)\r
-        {\r
-            var g = Array.FindIndex(new[] {"A", "B", "C", "D"}, x => x == comboBoxGroup.Text);\r
-            if (g == -1)\r
-                return ships;\r
-            return from s in ships where _groupSettings[g].Contains(s.Id) select s;\r
-        }\r
-\r
-        private class CompareShip : IComparer<ShipStatus>\r
-        {\r
-            private readonly bool _type;\r
-            private readonly SortOrder _order;\r
-\r
-            public CompareShip(bool type, SortOrder order)\r
-            {\r
-                _type = type;\r
-                _order = order;\r
-            }\r
-\r
-            public int Compare(ShipStatus a, ShipStatus b)\r
-            {\r
-                if (_type && a.Spec.ShipType != b.Spec.ShipType)\r
-                    return a.Spec.ShipType - b.Spec.ShipType;\r
-                switch (_order)\r
-                {\r
-                    case SortOrder.None:\r
-                    case SortOrder.ExpToNext:\r
-                        break;\r
-                    case SortOrder.Cond:\r
-                        if (a.Cond != b.Cond)\r
-                            return a.Cond - b.Cond;\r
-                        break;\r
-                    case SortOrder.Repair:\r
-                        if (a.RepairTime != b.RepairTime)\r
-                            return (int)(b.RepairTime - a.RepairTime).TotalSeconds;\r
-                        break;\r
-                }\r
-                if ((!_type || _order == SortOrder.ExpToNext) && a.Level != b.Level)\r
-                    return b.Level - a.Level;\r
-                if (_order == SortOrder.ExpToNext && a.ExpToNext != b.ExpToNext)\r
-                    return a.ExpToNext - b.ExpToNext;\r
-                if (a.Spec.SortNo != b.Spec.SortNo)\r
-                    return a.Spec.SortNo - b.Spec.SortNo;\r
-                return a.Id - b.Id;\r
-            }\r
-        }\r
-\r
-        private void CreateListLabels()\r
-        {\r
-            panelShipList.SuspendLayout();\r
-            for (var i = _labelList.Count; i < _shipList.Length; i++)\r
-            {\r
-                CreateConfigComponents(i);\r
-                CreateRepairLabels(i);\r
-                CreateShipLabels(i);\r
-            }\r
-            panelShipList.ResumeLayout();\r
-        }\r
-\r
-        private void CreateConfigComponents(int i)\r
-        {\r
-            var y = 3 + LineHeight * i;\r
-            var cfgp = new Panel\r
-            {\r
-                Location = new Point(0, y - 2),\r
-                Size = new Size(PanelWidth, LineHeight - 1),\r
-                BackColor = ShipLabels.ColumnColors[(i + 1) % 2],\r
-                Visible = false\r
-            };\r
-            cfgp.Scale(ShipLabel.ScaleFactor);\r
-            cfgp.Tag = cfgp.Location.Y;\r
-            var cfgl = new[]\r
-            {\r
-                new ShipLabel\r
-                {\r
-                    Location = new Point(91, 2),\r
-                    Size = new Size(23, LabelHeight),\r
-                    TextAlign = ContentAlignment.MiddleRight,\r
-                },\r
-                new ShipLabel {Location = new Point(10, 2), AutoSize = true},\r
-                new ShipLabel {Location = new Point(1, 2), AutoSize = true}\r
-            };\r
-\r
-            var cb = new CheckBox[GroupCount];\r
-            for (var j = 0; j < cb.Length; j++)\r
-            {\r
-                cb[j] = new CheckBox\r
-                {\r
-                    Location = new Point(125 + j * 24, 2),\r
-                    FlatStyle = FlatStyle.Flat,\r
-                    Size = new Size(12, 11),\r
-                    Tag = i * 10 + j\r
-                };\r
-                cb[j].Scale(ShipLabel.ScaleFactor);\r
-                cb[j].CheckedChanged += checkboxGroup_CheckedChanged;\r
-            }\r
-            _configLabelList.Add(cfgl);\r
-            _checkBoxesList.Add(cb);\r
-            _checkBoxPanelList.Add(cfgp);\r
-            // ReSharper disable CoVariantArrayConversion\r
-            cfgp.Controls.AddRange(cfgl);\r
-            cfgp.Controls.AddRange(cb);\r
-            // ReSharper restore CoVariantArrayConversion\r
-            panelShipList.Controls.Add(cfgp);\r
-            foreach (var label in cfgl)\r
-            {\r
-                label.Scale();\r
-                label.PresetColor =\r
-                    label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
-            }\r
-        }\r
-\r
-        private void CreateRepairLabels(int i)\r
-        {\r
-            var y = 3 + LineHeight * i;\r
-            const int height = LabelHeight;\r
-            var rpp = new Panel\r
-            {\r
-                Location = new Point(0, y - 2),\r
-                Size = new Size(PanelWidth, LineHeight - 1),\r
-                BackColor = ShipLabels.ColumnColors[(i + 1) % 2],\r
-                Visible = false\r
-            };\r
-            rpp.Scale(ShipLabel.ScaleFactor);\r
-            rpp.Tag = rpp.Location.Y;\r
-            var rpl = new[]\r
-            {\r
-                new ShipLabel {Location = new Point(118, 2), AutoSize = true, AnchorRight = true},\r
-                new ShipLabel\r
-                {\r
-                    Location = new Point(117, 2),\r
-                    Size = new Size(23, height),\r
-                    TextAlign = ContentAlignment.MiddleRight\r
-                },\r
-                new ShipLabel {Location = new Point(141, 2), AutoSize = true},\r
-                new ShipLabel {Location = new Point(186, 2), AutoSize = true},\r
-                new ShipLabel {Location = new Point(10, 2), AutoSize = true},\r
-                new ShipLabel {Location = new Point(1, 2), AutoSize = true}\r
-            };\r
-            _repairLabelList.Add(rpl);\r
-            _repairPanelList.Add(rpp);\r
-// ReSharper disable once CoVariantArrayConversion\r
-            rpp.Controls.AddRange(rpl);\r
-            panelShipList.Controls.Add(rpp);\r
-            foreach (var label in rpl)\r
-            {\r
-                label.Scale();\r
-                label.PresetColor =\r
-                    label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
-            }\r
-        }\r
-\r
-        private void CreateShipLabels(int i)\r
-        {\r
-            var y = 3 + LineHeight * i;\r
-            const int height = LabelHeight;\r
-            var lbp = new Panel\r
-            {\r
-                Location = new Point(0, y - 2),\r
-                Size = new Size(PanelWidth, LineHeight - 1),\r
-                BackColor = ShipLabels.ColumnColors[(i + 1) % 2],\r
-                Visible = false\r
-            };\r
-            lbp.Scale(ShipLabel.ScaleFactor);\r
-            lbp.Tag = lbp.Location.Y;\r
-            var labels = new[]\r
-            {\r
-                new ShipLabel {Location = new Point(126, 2), AutoSize = true, AnchorRight = true},\r
-                new ShipLabel\r
-                {\r
-                    Location = new Point(129, 2),\r
-                    Size = new Size(23, height),\r
-                    TextAlign = ContentAlignment.MiddleRight\r
-                },\r
-                new ShipLabel\r
-                {\r
-                    Location = new Point(155, 2),\r
-                    Size = new Size(23, height),\r
-                    TextAlign = ContentAlignment.MiddleRight\r
-                },\r
-                new ShipLabel\r
-                {\r
-                    Location = new Point(176, 2),\r
-                    Size = new Size(41, height),\r
-                    TextAlign = ContentAlignment.MiddleRight\r
-                },\r
-                new ShipLabel {Location = new Point(10, 2), AutoSize = true},\r
-                new ShipLabel {Location = new Point(1, 2), AutoSize = true}\r
-            };\r
-            _labelList.Add(labels);\r
-            _labelPanelList.Add(lbp);\r
-// ReSharper disable once CoVariantArrayConversion\r
-            lbp.Controls.AddRange(labels);\r
-            panelShipList.Controls.Add(lbp);\r
-            foreach (var label in labels)\r
-            {\r
-                label.Scale();\r
-                label.PresetColor =\r
-                    label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
-            }\r
-        }\r
-\r
-        private void SetShipLabels()\r
-        {\r
-            panelShipList.SuspendLayout();\r
-            for (var i = 0; i < _shipList.Length; i++)\r
-            {\r
-                if (!InShipStatus)\r
-                    _labelPanelList[i].Visible = false;\r
-                if (!InGroupConfig)\r
-                    _checkBoxPanelList[i].Visible = false;\r
-                if (!InRepairList)\r
-                    _repairPanelList[i].Visible = false;\r
-            }\r
-            for (var i = 0; i < _shipList.Length; i++)\r
-            {\r
-                if (InShipStatus)\r
-                    SetShipStatus(i);\r
-                if (InGroupConfig)\r
-                    SetGroupConfig(i);\r
-                if (InRepairList)\r
-                    SetRepairList(i);\r
-            }\r
-            for (var i = _shipList.Length; i < _labelPanelList.Count; i++)\r
-            {\r
-                _labelPanelList[i].Visible = _checkBoxPanelList[i].Visible = _repairPanelList[i].Visible = false;\r
-            }\r
-            panelShipList.ResumeLayout();\r
-        }\r
-\r
-        private void SetShipStatus(int i)\r
-        {\r
-            var lbp = _labelPanelList[i];\r
-            if (!lbp.Visible)\r
-                lbp.Location = new Point(lbp.Left, (int)lbp.Tag + panelShipList.AutoScrollPosition.Y);\r
-            var s = _shipList[i];\r
-            var labels = _labelList[i];\r
-            if (s.Level == 1000) // 艦種の表示\r
-            {\r
-                SetShipType(i);\r
-                return;\r
-            }\r
-            labels[0].SetHp(s);\r
-            labels[1].SetCond(s);\r
-            labels[2].SetLevel(s);\r
-            labels[3].SetExpToNext(s);\r
-            labels[4].SetName(s, ShipNameWidth.ShipList);\r
-            labels[5].SetFleet(s);\r
-            lbp.Visible = true;\r
-        }\r
-\r
-        private void SetShipType(int i)\r
-        {\r
-            var lbp = _labelPanelList[i];\r
-            if (!lbp.Visible)\r
-                lbp.Location = new Point(lbp.Left, (int)lbp.Tag + panelShipList.AutoScrollPosition.Y);\r
-            var s = _shipList[i];\r
-            var labels = _labelList[i];\r
-            for (var c = 0; c < 4; c++)\r
-            {\r
-                labels[c].Text = "";\r
-                labels[c].BackColor = labels[c].PresetColor;\r
-            }\r
-            labels[4].SetName("");\r
-            labels[5].Text = s.Name;\r
-            lbp.Visible = true;\r
-        }\r
-\r
-        private void SetGroupConfig(int i)\r
-        {\r
-            var cbp = _checkBoxPanelList[i];\r
-            var s = _shipList[i];\r
-            if (s.Level == 1000)\r
-            {\r
-                SetShipType(i);\r
-                cbp.Visible = false;\r
-                return;\r
-            }\r
-            if (!cbp.Visible)\r
-                cbp.Location = new Point(cbp.Left, (int)cbp.Tag + panelShipList.AutoScrollPosition.Y);\r
-            var cfgl = _configLabelList[i];\r
-            cfgl[0].SetLevel(s);\r
-            cfgl[1].SetName(s, ShipNameWidth.GroupConfig);\r
-            cfgl[2].SetFleet(s);\r
-            var cb = _checkBoxesList[i];\r
-            for (var j = 0; j < cb.Length; j++)\r
-                cb[j].Checked = _groupSettings[j].Contains(s.Id);\r
-            cbp.Visible = true;\r
-        }\r
-\r
-        private void SetRepairList(int i)\r
-        {\r
-            var rpp = _repairPanelList[i];\r
-            var s = _shipList[i];\r
-            if (s.Level == 1000)\r
-            {\r
-                SetShipType(i);\r
-                rpp.Visible = false;\r
-                return;\r
-            }\r
-            if (!rpp.Visible)\r
-                rpp.Location = new Point(rpp.Left, (int)rpp.Tag + panelShipList.AutoScrollPosition.Y);\r
-            var rpl = _repairLabelList[i];\r
-            rpl[0].SetHp(s);\r
-            rpl[1].SetLevel(s);\r
-            rpl[2].SetRepairTime(s);\r
-            rpl[3].Text = TimeSpan.FromSeconds(s.RepairSecPerHp).ToString(@"mm\:ss");\r
-            rpl[4].SetName(s, ShipNameWidth.RepairListFull);\r
-            rpl[5].SetFleet(s);\r
-            rpp.Visible = true;\r
-        }\r
-\r
         private bool InShipStatus => Array.Exists(new[] {"全員", "A", "B", "C", "D"}, x => comboBoxGroup.Text == x);\r
 \r
         private bool InGroupConfig => comboBoxGroup.Text == "分類";\r
@@ -455,18 +108,20 @@ namespace KancolleSniffer
 \r
         private void ShipListForm_Load(object sender, EventArgs e)\r
         {\r
-            panelShipList.Width = itemTreeView.Width = equipPanel.Width =\r
+            shipListPanel.Width = itemTreeView.Width = equipPanel.Width =\r
                 (int)Round(PanelWidth * ShipLabel.ScaleFactor.Width) + 3 + SystemInformation.VerticalScrollBarWidth;\r
-            Width = panelShipList.Width + 12 + (Width - ClientSize.Width);\r
+            Width = shipListPanel.Width + 12 + (Width - ClientSize.Width);\r
             MinimumSize = new Size(Width, 0);\r
             MaximumSize = new Size(Width, int.MaxValue);\r
             var config = _config.ShipList;\r
             checkBoxShipType.Checked = config.ShipType;\r
-            ActiveControl = panelShipList;\r
-            for (var i = 0; i < GroupCount; i++)\r
-                _groupSettings[i] = i < config.ShipGroup.Count\r
+            ActiveControl = shipListPanel;\r
+            for (var i = 0; i < ShipListPanel.GroupCount; i++)\r
+            {\r
+                shipListPanel.GroupSettings[i] = i < config.ShipGroup.Count\r
                     ? new HashSet<int>(config.ShipGroup[i])\r
                     : new HashSet<int>();\r
+            }\r
             comboBoxGroup.SelectedIndex = 0;\r
             if (config.Location.X == int.MinValue)\r
                 return;\r
@@ -484,11 +139,11 @@ namespace KancolleSniffer
             var config = _config.ShipList;\r
             var all = _sniffer.ShipList.Select(s => s.Id).ToArray();\r
             config.ShipGroup.Clear();\r
-            for (var i = 0; i < GroupCount; i++)\r
+            for (var i = 0; i < ShipListPanel.GroupCount; i++)\r
             {\r
                 if (all.Length > 0)\r
-                    _groupSettings[i].IntersectWith(all);\r
-                config.ShipGroup.Add(_groupSettings[i].ToList());\r
+                    shipListPanel.GroupSettings[i].IntersectWith(all);\r
+                config.ShipGroup.Add(shipListPanel.GroupSettings[i].ToList());\r
             }\r
             var bounds = WindowState == FormWindowState.Normal ? Bounds : RestoreBounds;\r
             config.Location = bounds.Location;\r
@@ -500,11 +155,7 @@ namespace KancolleSniffer
         {\r
             if (InShipStatus)\r
             {\r
-                var i = Array.FindIndex(_shipList, s => s.Id == id);\r
-                if (i == -1)\r
-                    return;\r
-                var y = (int)Round(ShipLabel.ScaleFactor.Height * LineHeight * i);\r
-                panelShipList.AutoScrollPosition = new Point(0, y);\r
+                shipListPanel.ShowShip(id);\r
             }\r
             else if (InEquip)\r
             {\r
@@ -519,17 +170,6 @@ namespace KancolleSniffer
             SetActiveControl();\r
         }\r
 \r
-        private void checkboxGroup_CheckedChanged(object sender, EventArgs e)\r
-        {\r
-            var cb = (CheckBox)sender;\r
-            var group = (int)cb.Tag % 10;\r
-            var idx = (int)cb.Tag / 10;\r
-            if (cb.Checked)\r
-                _groupSettings[group].Add(_shipList[idx].Id);\r
-            else\r
-                _groupSettings[group].Remove(_shipList[idx].Id);\r
-        }\r
-\r
         private void comboBoxGroup_DropDownClosed(object sender, EventArgs e)\r
         {\r
             SetActiveControl();\r
@@ -556,11 +196,17 @@ namespace KancolleSniffer
         private void SetActiveControl()\r
         {\r
             if (InItemList)\r
+            {\r
                 ActiveControl = itemTreeView;\r
+            }\r
             else if (InEquip)\r
+            {\r
                 ActiveControl = equipPanel;\r
+            }\r
             else\r
-                ActiveControl = panelShipList;\r
+            {\r
+                ActiveControl = shipListPanel;\r
+            }\r
         }\r
 \r
         private void copyToolStripMenuItem_Click(object sender, EventArgs e)\r
@@ -586,18 +232,20 @@ namespace KancolleSniffer
 \r
         private void labelHeaderExp_Click(object sender, EventArgs e)\r
         {\r
-            _config.ShipList.SortOrder = _config.ShipList.SortOrder == SortOrder.ExpToNext ? SortOrder.None : SortOrder.ExpToNext;\r
+            _config.ShipList.SortOrder = _config.ShipList.SortOrder == SortOrder.ExpToNext\r
+                ? SortOrder.None\r
+                : SortOrder.ExpToNext;\r
             UpdateList();\r
         }\r
 \r
         private void csvToolStripMenuItem_Click(object sender, EventArgs e)\r
         {\r
-            Clipboard.SetText(TextGenerator.GenerateShipList(FilterByGroup(_sniffer.ShipList)));\r
+            Clipboard.SetText(TextGenerator.GenerateShipList(shipListPanel.CurrentShipList));\r
         }\r
 \r
         private void kantaiSarashiToolStripMenuItem_Click(object sender, EventArgs e)\r
         {\r
-            Clipboard.SetText(TextGenerator.GenerateKantaiSarashiData(FilterByGroup(_sniffer.ShipList)));\r
+            Clipboard.SetText(TextGenerator.GenerateKantaiSarashiData(shipListPanel.CurrentShipList));\r
         }\r
     }\r
 }
\ No newline at end of file
diff --git a/KancolleSniffer/ShipListPanel.cs b/KancolleSniffer/ShipListPanel.cs
new file mode 100644 (file)
index 0000000..84bfe61
--- /dev/null
@@ -0,0 +1,407 @@
+// Copyright (C) 2016 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.Collections.Generic;\r
+using System.Drawing;\r
+using System.Linq;\r
+using System.Windows.Forms;\r
+\r
+namespace KancolleSniffer\r
+{\r
+    public class ShipListPanel : Panel\r
+    {\r
+        private const int LabelHeight = 12;\r
+        private const int LineHeight = 16;\r
+        private ShipStatus[] _shipList;\r
+        private readonly List<ShipLabel[]> _labelList = new List<ShipLabel[]>();\r
+        private readonly List<Panel> _labelPanelList = new List<Panel>();\r
+        private readonly List<CheckBox[]> _checkBoxesList = new List<CheckBox[]>();\r
+        private readonly List<ShipLabel[]> _configLabelList = new List<ShipLabel[]>();\r
+        private readonly List<Panel> _checkBoxPanelList = new List<Panel>();\r
+        private readonly List<ShipLabel[]> _repairLabelList = new List<ShipLabel[]>();\r
+        private readonly List<Panel> _repairPanelList = new List<Panel>();\r
+\r
+        public const int GroupCount = 4;\r
+        public HashSet<int>[] GroupSettings { get; } = new HashSet<int>[GroupCount];\r
+\r
+        public void Update(Sniffer sniffer, string mode, ListForm.SortOrder sortOrder, bool byShipType)\r
+        {\r
+            CreateShipList(sniffer, mode, sortOrder, byShipType);\r
+            CreateListLabels();\r
+            SetShipLabels(mode);\r
+        }\r
+\r
+        void CreateShipList(Sniffer sniffer, string mode, ListForm.SortOrder sortOrder, bool byShipType)\r
+        {\r
+            var ships = mode == "修復" ? sniffer.RepairList : FilterByGroup(sniffer.ShipList, mode).ToArray();\r
+            var order = mode == "修復" ? ListForm.SortOrder.Repair : sortOrder;\r
+            if (!byShipType)\r
+            {\r
+                _shipList = ships.OrderBy(s => s, new CompareShip(false, order)).ToArray();\r
+                return;\r
+            }\r
+            var types = ships.Select(s => new {Id = s.Spec.ShipType, Name = s.Spec.ShipTypeName}).Distinct().\r
+                Select(stype =>\r
+                    new ShipStatus\r
+                    {\r
+                        Spec = new ShipSpec {Name = stype.Name, ShipType = stype.Id},\r
+                        Level = 1000,\r
+                        NowHp = -1000,\r
+                        Cond = -1000\r
+                    });\r
+            _shipList = ships.Concat(types).OrderBy(s => s, new CompareShip(true, order)).ToArray();\r
+        }\r
+\r
+        private IEnumerable<ShipStatus> FilterByGroup(IEnumerable<ShipStatus> ships, string group)\r
+        {\r
+            var g = Array.FindIndex(new[] {"A", "B", "C", "D"}, x => x == group);\r
+            if (g == -1)\r
+                return ships;\r
+            return from s in ships where GroupSettings[g].Contains(s.Id) select s;\r
+        }\r
+\r
+        public IEnumerable<ShipStatus> CurrentShipList => _shipList.Where(ship => ship.Level != 1000);\r
+\r
+        private class CompareShip : IComparer<ShipStatus>\r
+        {\r
+            private readonly bool _type;\r
+            private readonly ListForm.SortOrder _order;\r
+\r
+            public CompareShip(bool type, ListForm.SortOrder order)\r
+            {\r
+                _type = type;\r
+                _order = order;\r
+            }\r
+\r
+            public int Compare(ShipStatus a, ShipStatus b)\r
+            {\r
+                if (_type && a.Spec.ShipType != b.Spec.ShipType)\r
+                    return a.Spec.ShipType - b.Spec.ShipType;\r
+                switch (_order)\r
+                {\r
+                    case ListForm.SortOrder.None:\r
+                    case ListForm.SortOrder.ExpToNext:\r
+                        break;\r
+                    case ListForm.SortOrder.Cond:\r
+                        if (a.Cond != b.Cond)\r
+                            return a.Cond - b.Cond;\r
+                        break;\r
+                    case ListForm.SortOrder.Repair:\r
+                        if (a.RepairTime != b.RepairTime)\r
+                            return (int)(b.RepairTime - a.RepairTime).TotalSeconds;\r
+                        break;\r
+                }\r
+                if ((!_type || _order == ListForm.SortOrder.ExpToNext) && a.Level != b.Level)\r
+                    return b.Level - a.Level;\r
+                if (_order == ListForm.SortOrder.ExpToNext && a.ExpToNext != b.ExpToNext)\r
+                    return a.ExpToNext - b.ExpToNext;\r
+                if (a.Spec.SortNo != b.Spec.SortNo)\r
+                    return a.Spec.SortNo - b.Spec.SortNo;\r
+                return a.Id - b.Id;\r
+            }\r
+        }\r
+\r
+        private void CreateListLabels()\r
+        {\r
+            SuspendLayout();\r
+            for (var i = _labelList.Count; i < _shipList.Length; i++)\r
+            {\r
+                CreateConfigComponents(i);\r
+                CreateRepairLabels(i);\r
+                CreateShipLabels(i);\r
+            }\r
+            ResumeLayout();\r
+        }\r
+\r
+        private void CreateConfigComponents(int i)\r
+        {\r
+            var y = 3 + LineHeight * i;\r
+            var cfgp = new Panel\r
+            {\r
+                Location = new Point(0, y - 2),\r
+                Size = new Size(ListForm.PanelWidth, LineHeight - 1),\r
+                BackColor = ShipLabels.ColumnColors[(i + 1) % 2],\r
+                Visible = false\r
+            };\r
+            cfgp.Scale(ShipLabel.ScaleFactor);\r
+            cfgp.Tag = cfgp.Location.Y;\r
+            var cfgl = new[]\r
+            {\r
+                new ShipLabel\r
+                {\r
+                    Location = new Point(91, 2),\r
+                    Size = new Size(23, LabelHeight),\r
+                    TextAlign = ContentAlignment.MiddleRight,\r
+                },\r
+                new ShipLabel {Location = new Point(10, 2), AutoSize = true},\r
+                new ShipLabel {Location = new Point(1, 2), AutoSize = true}\r
+            };\r
+\r
+            var cb = new CheckBox[GroupCount];\r
+            for (var j = 0; j < cb.Length; j++)\r
+            {\r
+                cb[j] = new CheckBox\r
+                {\r
+                    Location = new Point(125 + j * 24, 2),\r
+                    FlatStyle = FlatStyle.Flat,\r
+                    Size = new Size(12, 11),\r
+                    Tag = i * 10 + j\r
+                };\r
+                cb[j].Scale(ShipLabel.ScaleFactor);\r
+                cb[j].CheckedChanged += checkboxGroup_CheckedChanged;\r
+            }\r
+            _configLabelList.Add(cfgl);\r
+            _checkBoxesList.Add(cb);\r
+            _checkBoxPanelList.Add(cfgp);\r
+            // ReSharper disable CoVariantArrayConversion\r
+            cfgp.Controls.AddRange(cfgl);\r
+            cfgp.Controls.AddRange(cb);\r
+            // ReSharper restore CoVariantArrayConversion\r
+            Controls.Add(cfgp);\r
+            foreach (var label in cfgl)\r
+            {\r
+                label.Scale();\r
+                label.PresetColor =\r
+                    label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
+            }\r
+        }\r
+\r
+        private void checkboxGroup_CheckedChanged(object sender, EventArgs e)\r
+        {\r
+            var cb = (CheckBox)sender;\r
+            var group = (int)cb.Tag % 10;\r
+            var idx = (int)cb.Tag / 10;\r
+            if (cb.Checked)\r
+            {\r
+                GroupSettings[group].Add(_shipList[idx].Id);\r
+            }\r
+            else\r
+            {\r
+                GroupSettings[group].Remove(_shipList[idx].Id);\r
+            }\r
+        }\r
+\r
+        private void CreateRepairLabels(int i)\r
+        {\r
+            var y = 3 + LineHeight * i;\r
+            const int height = LabelHeight;\r
+            var rpp = new Panel\r
+            {\r
+                Location = new Point(0, y - 2),\r
+                Size = new Size(ListForm.PanelWidth, LineHeight - 1),\r
+                BackColor = ShipLabels.ColumnColors[(i + 1) % 2],\r
+                Visible = false\r
+            };\r
+            rpp.Scale(ShipLabel.ScaleFactor);\r
+            rpp.Tag = rpp.Location.Y;\r
+            var rpl = new[]\r
+            {\r
+                new ShipLabel {Location = new Point(118, 2), AutoSize = true, AnchorRight = true},\r
+                new ShipLabel\r
+                {\r
+                    Location = new Point(117, 2),\r
+                    Size = new Size(23, height),\r
+                    TextAlign = ContentAlignment.MiddleRight\r
+                },\r
+                new ShipLabel {Location = new Point(141, 2), AutoSize = true},\r
+                new ShipLabel {Location = new Point(186, 2), AutoSize = true},\r
+                new ShipLabel {Location = new Point(10, 2), AutoSize = true},\r
+                new ShipLabel {Location = new Point(1, 2), AutoSize = true}\r
+            };\r
+            _repairLabelList.Add(rpl);\r
+            _repairPanelList.Add(rpp);\r
+            // ReSharper disable once CoVariantArrayConversion\r
+            rpp.Controls.AddRange(rpl);\r
+            Controls.Add(rpp);\r
+            foreach (var label in rpl)\r
+            {\r
+                label.Scale();\r
+                label.PresetColor =\r
+                    label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
+            }\r
+        }\r
+\r
+        private void CreateShipLabels(int i)\r
+        {\r
+            var y = 3 + LineHeight * i;\r
+            const int height = LabelHeight;\r
+            var lbp = new Panel\r
+            {\r
+                Location = new Point(0, y - 2),\r
+                Size = new Size(ListForm.PanelWidth, LineHeight - 1),\r
+                BackColor = ShipLabels.ColumnColors[(i + 1) % 2],\r
+                Visible = false\r
+            };\r
+            lbp.Scale(ShipLabel.ScaleFactor);\r
+            lbp.Tag = lbp.Location.Y;\r
+            var labels = new[]\r
+            {\r
+                new ShipLabel {Location = new Point(126, 2), AutoSize = true, AnchorRight = true},\r
+                new ShipLabel\r
+                {\r
+                    Location = new Point(129, 2),\r
+                    Size = new Size(23, height),\r
+                    TextAlign = ContentAlignment.MiddleRight\r
+                },\r
+                new ShipLabel\r
+                {\r
+                    Location = new Point(155, 2),\r
+                    Size = new Size(23, height),\r
+                    TextAlign = ContentAlignment.MiddleRight\r
+                },\r
+                new ShipLabel\r
+                {\r
+                    Location = new Point(176, 2),\r
+                    Size = new Size(41, height),\r
+                    TextAlign = ContentAlignment.MiddleRight\r
+                },\r
+                new ShipLabel {Location = new Point(10, 2), AutoSize = true},\r
+                new ShipLabel {Location = new Point(1, 2), AutoSize = true}\r
+            };\r
+            _labelList.Add(labels);\r
+            _labelPanelList.Add(lbp);\r
+            // ReSharper disable once CoVariantArrayConversion\r
+            lbp.Controls.AddRange(labels);\r
+            Controls.Add(lbp);\r
+            foreach (var label in labels)\r
+            {\r
+                label.Scale();\r
+                label.PresetColor =\r
+                    label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
+            }\r
+        }\r
+\r
+        private void SetShipLabels(string mode)\r
+        {\r
+            SuspendLayout();\r
+            for (var i = 0; i < _shipList.Length; i++)\r
+            {\r
+                if (!InShipStatus(mode))\r
+                    _labelPanelList[i].Visible = false;\r
+                if (mode != "分類")\r
+                    _checkBoxPanelList[i].Visible = false;\r
+                if (mode != "修復")\r
+                    _repairPanelList[i].Visible = false;\r
+            }\r
+            for (var i = 0; i < _shipList.Length; i++)\r
+            {\r
+                if (InShipStatus(mode))\r
+                    SetShipStatus(i);\r
+                if (mode == "分類")\r
+                    SetGroupConfig(i);\r
+                if (mode == "修復")\r
+                    SetRepairList(i);\r
+            }\r
+            for (var i = _shipList.Length; i < _labelPanelList.Count; i++)\r
+            {\r
+                _labelPanelList[i].Visible = _checkBoxPanelList[i].Visible = _repairPanelList[i].Visible = false;\r
+            }\r
+            ResumeLayout();\r
+        }\r
+\r
+        private bool InShipStatus(string mode) => Array.Exists(new[] {"全員", "A", "B", "C", "D"}, x => mode == x);\r
+\r
+        private void SetShipStatus(int i)\r
+        {\r
+            var lbp = _labelPanelList[i];\r
+            if (!lbp.Visible)\r
+                lbp.Location = new Point(lbp.Left, (int)lbp.Tag + AutoScrollPosition.Y);\r
+            var s = _shipList[i];\r
+            var labels = _labelList[i];\r
+            if (s.Level == 1000) // 艦種の表示\r
+            {\r
+                SetShipType(i);\r
+                return;\r
+            }\r
+            labels[0].SetHp(s);\r
+            labels[1].SetCond(s);\r
+            labels[2].SetLevel(s);\r
+            labels[3].SetExpToNext(s);\r
+            labels[4].SetName(s, ShipNameWidth.ShipList);\r
+            labels[5].SetFleet(s);\r
+            lbp.Visible = true;\r
+        }\r
+\r
+        private void SetShipType(int i)\r
+        {\r
+            var lbp = _labelPanelList[i];\r
+            if (!lbp.Visible)\r
+                lbp.Location = new Point(lbp.Left, (int)lbp.Tag + AutoScrollPosition.Y);\r
+            var s = _shipList[i];\r
+            var labels = _labelList[i];\r
+            for (var c = 0; c < 4; c++)\r
+            {\r
+                labels[c].Text = "";\r
+                labels[c].BackColor = labels[c].PresetColor;\r
+            }\r
+            labels[4].SetName("");\r
+            labels[5].Text = s.Name;\r
+            lbp.Visible = true;\r
+        }\r
+\r
+        private void SetGroupConfig(int i)\r
+        {\r
+            var cbp = _checkBoxPanelList[i];\r
+            var s = _shipList[i];\r
+            if (s.Level == 1000)\r
+            {\r
+                SetShipType(i);\r
+                cbp.Visible = false;\r
+                return;\r
+            }\r
+            if (!cbp.Visible)\r
+                cbp.Location = new Point(cbp.Left, (int)cbp.Tag + AutoScrollPosition.Y);\r
+            var cfgl = _configLabelList[i];\r
+            cfgl[0].SetLevel(s);\r
+            cfgl[1].SetName(s, ShipNameWidth.GroupConfig);\r
+            cfgl[2].SetFleet(s);\r
+            var cb = _checkBoxesList[i];\r
+            for (var j = 0; j < cb.Length; j++)\r
+                cb[j].Checked = GroupSettings[j].Contains(s.Id);\r
+            cbp.Visible = true;\r
+        }\r
+\r
+        private void SetRepairList(int i)\r
+        {\r
+            var rpp = _repairPanelList[i];\r
+            var s = _shipList[i];\r
+            if (s.Level == 1000)\r
+            {\r
+                SetShipType(i);\r
+                rpp.Visible = false;\r
+                return;\r
+            }\r
+            if (!rpp.Visible)\r
+                rpp.Location = new Point(rpp.Left, (int)rpp.Tag + AutoScrollPosition.Y);\r
+            var rpl = _repairLabelList[i];\r
+            rpl[0].SetHp(s);\r
+            rpl[1].SetLevel(s);\r
+            rpl[2].SetRepairTime(s);\r
+            rpl[3].Text = TimeSpan.FromSeconds(s.RepairSecPerHp).ToString(@"mm\:ss");\r
+            rpl[4].SetName(s, ShipNameWidth.RepairListFull);\r
+            rpl[5].SetFleet(s);\r
+            rpp.Visible = true;\r
+        }\r
+\r
+        public void ShowShip(int id)\r
+        {\r
+            var i = Array.FindIndex(_shipList, s => s.Id == id);\r
+            if (i == -1)\r
+                return;\r
+            var y = (int)Math.Round(ShipLabel.ScaleFactor.Height * LineHeight * i);\r
+            AutoScrollPosition = new Point(0, y);\r
+        }\r
+    }\r
+}
\ No newline at end of file