OSDN Git Service

タイマーの時刻を保持するTimeStepクラスを導入する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / ListForm.cs
index 9303aed..75d5969 100644 (file)
@@ -18,7 +18,8 @@ using System.Drawing;
 using System.Linq;\r
 using System.Windows.Forms;\r
 using KancolleSniffer.View;\r
-using static System.Math;\r
+using KancolleSniffer.View.ShipListPanel;\r
+using Clipboard = KancolleSniffer.Util.Clipboard;\r
 \r
 namespace KancolleSniffer\r
 {\r
@@ -29,8 +30,58 @@ namespace KancolleSniffer
         private readonly MainForm _main;\r
         private readonly MainForm.TimeOutChecker _suppressActivate;\r
         private readonly CheckBox[] _shipTypeCheckBoxes;\r
+        private bool _isMaster;\r
+        private Settings _settings;\r
         public const int PanelWidth = 217;\r
 \r
+        public class Settings\r
+        {\r
+            public string Mode { get; set; }\r
+            public ShipCategory ShipCategories { get; set; }\r
+            public bool ShipType { get; set; }\r
+            public bool ShowHpInPercent { get; set; }\r
+            public SortOrder SortOrder { get; set; }\r
+\r
+            public static Settings FromShipListConfig(ShipListConfig config)\r
+            {\r
+                return new Settings\r
+                {\r
+                    Mode = config.Mode ?? "全艦",\r
+                    ShipCategories = config.ShipCategories,\r
+                    ShipType = config.ShipType,\r
+                    ShowHpInPercent = config.ShowHpInPercent,\r
+                    SortOrder = config.SortOrder\r
+                };\r
+            }\r
+\r
+            public void SetToShipListConfig(ShipListConfig config)\r
+            {\r
+                config.Mode = Mode;\r
+                config.ShipCategories = ShipCategories;\r
+                config.ShipType = ShipType;\r
+                config.ShowHpInPercent = ShowHpInPercent;\r
+                config.SortOrder = SortOrder;\r
+            }\r
+        }\r
+\r
+        private object[] PanelNames => new object[] {"全艦", "A", "B", "C", "D", "分類", "修復", "装備", "艦隊", "対空", "戦況", "情報"}\r
+            .Where(n => IsMaster || (string)n != "分類").ToArray();\r
+\r
+        private char[] PanelKeys => new[] {'Z', 'A', 'B', 'C', 'D', 'G', 'R', 'W', 'X', 'Y', 'S', 'I'}\r
+            .Where(key => IsMaster || key != 'G').ToArray();\r
+\r
+        public bool IsMaster\r
+        {\r
+            get => _isMaster;\r
+            set\r
+            {\r
+                _isMaster = value;\r
+                Text = _isMaster ? "一覧 プライマリ" : "一覧";\r
+                comboBoxGroup.Items.Clear();\r
+                comboBoxGroup.Items.AddRange(PanelNames);\r
+            }\r
+        }\r
+\r
         public enum SortOrder\r
         {\r
             None,\r
@@ -46,6 +97,7 @@ namespace KancolleSniffer
         public ListForm(MainForm main)\r
         {\r
             InitializeComponent();\r
+            IsMaster = false;\r
             _main = main;\r
             _sniffer = main.Sniffer;\r
             _config = main.Config;\r
@@ -92,7 +144,7 @@ namespace KancolleSniffer
             else if (InShipStatus || InGroupConfig || InRepairList)\r
             {\r
                 SetHeaderSortOrder();\r
-                shipListPanel.Update(_sniffer, comboBoxGroup.Text, _config.ShipList);\r
+                shipListPanel.Update(_sniffer, comboBoxGroup.Text, _settings);\r
             }\r
             if (shipListPanel.GroupUpdated)\r
             {\r
@@ -104,43 +156,34 @@ namespace KancolleSniffer
 \r
         private void SetHeaderVisibility()\r
         {\r
-            var headers = new[]\r
-            {\r
-                new {Header = panelItemHeader, Visible = InItemList || InAntiAir || InBattleResult || InMiscText},\r
-                new {Header = panelGroupHeader, Visible = InGroupConfig},\r
-                new {Header = panelRepairHeader, Visible = InRepairList},\r
-                new {Header = panelFleetHeader, Visible = InFleetInfo}\r
-            };\r
-            foreach (var header in headers)\r
+            static void Set(Control header, bool visible)\r
             {\r
-                if (header.Visible)\r
-                {\r
-                    header.Header.Visible = true;\r
-                    header.Header.BringToFront();\r
-                }\r
-                else\r
-                {\r
-                    header.Header.Visible = false;\r
-                }\r
+                header.Visible = visible;\r
+                if (visible)\r
+                    header.BringToFront();\r
             }\r
-        }\r
 \r
+            Set(panelItemHeader, InItemList || InAntiAir || InBattleResult || InMiscText);\r
+            Set(panelGroupHeader, InGroupConfig);\r
+            Set(panelRepairHeader, InRepairList);\r
+            Set(panelFleetHeader, InFleetInfo);\r
+        }\r
 \r
         private void SetPanelVisibility()\r
         {\r
-            SetVisible(shipListPanel, InShipStatus || InGroupConfig || InRepairList);\r
-            SetVisible(itemTreeView, InItemList);\r
-            SetVisible(fleetPanel, InFleetInfo);\r
-            SetVisible(antiAirPanel, InAntiAir);\r
-            SetVisible(airBattleResultPanel, InBattleResult);\r
-            SetVisible(battleResultPanel, InBattleResult);\r
-            SetVisible(richTextBoxMiscText, InMiscText);\r
-        }\r
+            static void Set(Control panel, bool visible)\r
+            {\r
+                // SwipeScrollifyが誤作動するのでEnabledも切り替える\r
+                panel.Visible = panel.Enabled = visible;\r
+            }\r
 \r
-        private void SetVisible(Control control, bool visible)\r
-        {\r
-            // SwipeScrollifyが誤作動するのでEnabledも切り替える\r
-            control.Visible = control.Enabled = visible;\r
+            Set(shipListPanel, InShipStatus || InGroupConfig || InRepairList);\r
+            Set(itemTreeView, InItemList);\r
+            Set(fleetPanel, InFleetInfo);\r
+            Set(antiAirPanel, InAntiAir);\r
+            Set(airBattleResultPanel, InBattleResult);\r
+            Set(battleResultPanel, InBattleResult);\r
+            Set(richTextBoxMiscText, InMiscText);\r
         }\r
 \r
         public void UpdateAirBattleResult()\r
@@ -151,8 +194,30 @@ namespace KancolleSniffer
 \r
         public void UpdateBattleResult()\r
         {\r
+            MoveToBattleResult();\r
             battleResultPanel.Spoilers = _config.Spoilers;\r
             battleResultPanel.Update(_sniffer);\r
+            BackFromBattleResult();\r
+        }\r
+\r
+        private int _prevSelectedIndex = -1;\r
+        private const int BattleResultIndex = 10;\r
+\r
+        private void MoveToBattleResult()\r
+        {\r
+            if (!_isMaster || !_config.ShipList.AutoBattleResult || comboBoxGroup.SelectedIndex == BattleResultIndex ||\r
+                _sniffer.InSortie == -1)\r
+                return;\r
+            _prevSelectedIndex = comboBoxGroup.SelectedIndex;\r
+            comboBoxGroup.SelectedIndex = BattleResultIndex;\r
+        }\r
+\r
+        private void BackFromBattleResult()\r
+        {\r
+            if (_sniffer.InSortie != -1 || _prevSelectedIndex == -1)\r
+                return;\r
+            comboBoxGroup.SelectedIndex = _prevSelectedIndex;\r
+            _prevSelectedIndex = -1;\r
         }\r
 \r
         public void UpdateCellInfo()\r
@@ -163,7 +228,7 @@ namespace KancolleSniffer
 \r
         private void SetHeaderSortOrder()\r
         {\r
-            switch (_config.ShipList.SortOrder)\r
+            switch (_settings.SortOrder)\r
             {\r
                 case SortOrder.None:\r
                     labelHeaderCond.Text = "cond";\r
@@ -188,39 +253,40 @@ namespace KancolleSniffer
             }\r
         }\r
 \r
-        private bool InShipStatus => Array.Exists(new[] {"全艦", "A", "B", "C", "D"}, x => comboBoxGroup.Text == x);\r
+        private bool InShipStatus => Array.Exists(new[] {"全艦", "A", "B", "C", "D"}, x => _settings.Mode == x);\r
 \r
-        private bool InGroupConfig => comboBoxGroup.Text == "分類";\r
+        private bool InGroupConfig => _settings.Mode == "分類";\r
 \r
-        private bool InRepairList => comboBoxGroup.Text == "修復";\r
+        private bool InRepairList => _settings.Mode == "修復";\r
 \r
-        private bool InItemList => comboBoxGroup.Text == "装備";\r
+        private bool InItemList => _settings.Mode == "装備";\r
 \r
-        private bool InFleetInfo => comboBoxGroup.Text == "艦隊";\r
+        private bool InFleetInfo => _settings.Mode == "艦隊";\r
 \r
-        private bool InAntiAir => comboBoxGroup.Text == "対空";\r
+        private bool InAntiAir => _settings.Mode == "対空";\r
 \r
-        private bool InBattleResult => comboBoxGroup.Text == "戦況";\r
+        private bool InBattleResult => _settings.Mode == "戦況";\r
 \r
-        private bool InMiscText => comboBoxGroup.Text == "情報";\r
+        private bool InMiscText => _settings.Mode == "情報";\r
 \r
         private void ListForm_Load(object sender, EventArgs e)\r
         {\r
             /* DPIではなくズームしたときにパネルは大きくなるがScrollBarはそのままなので隙間ができる。\r
                そこでScrollBarの幅に合わせて全体の横幅を設定し直す。*/\r
-            Width = (int)Round((PanelWidth + 12 /* PanelとFrameの内側 */) * ShipLabel.ScaleFactor.Width) +\r
+            Width = Scaler.ScaleWidth(PanelWidth + 12 /* PanelとFrameの内側 */) +\r
                     SystemInformation.VerticalScrollBarWidth + 2 /* 縁の幅 */ + Width - ClientSize.Width;\r
             MinimumSize = new Size(Width, 0);\r
             MaximumSize = new Size(Width, int.MaxValue);\r
-            var config = _config.ShipList;\r
-            if (config.ShowHpInPercent)\r
+            var config = GetConfig();\r
+            _settings = Settings.FromShipListConfig(config);\r
+            if (_settings.ShowHpInPercent)\r
             {\r
                 shipListPanel.ToggleHpPercent();\r
                 battleResultPanel.ToggleHpPercent();\r
             }\r
             LoadShipGroupFromConfig();\r
-            comboBoxGroup.SelectedItem = config.Mode ?? "全艦";\r
-            SetCheckBoxSTypeSate();\r
+            comboBoxGroup.SelectedItem = _settings.Mode;\r
+            SetCheckBoxSTypeState();\r
             if (config.Location.X == int.MinValue)\r
                 return;\r
             var bounds = new Rectangle(config.Location, config.Size);\r
@@ -229,33 +295,78 @@ namespace KancolleSniffer
             Height = bounds.Height;\r
         }\r
 \r
+        private ShipListConfig GetConfig()\r
+        {\r
+            if (_isMaster || _config.ListFormGroup.Count == 0)\r
+                return _config.ShipList;\r
+            var config = _config.ListFormGroup[0];\r
+            _config.ListFormGroup.RemoveAt(0);\r
+            if (config.Mode == "分類")\r
+                config.Mode = "全艦";\r
+            return config;\r
+        }\r
+\r
         private void LoadShipGroupFromConfig()\r
         {\r
             var group = _config.ShipList.ShipGroup;\r
-            for (var i = 0; i < ShipListPanel.GroupCount; i++)\r
+            for (var i = 0; i < GroupConfigLabels.GroupCount; i++)\r
                 shipListPanel.GroupSettings[i] = i < group.Count ? new HashSet<int>(group[i]) : new HashSet<int>();\r
         }\r
 \r
-        private void SetCheckBoxSTypeSate()\r
+        private void SetCheckBoxSTypeState()\r
         {\r
             for (var type = 0; type < _shipTypeCheckBoxes.Length; type++)\r
-                _shipTypeCheckBoxes[type].Checked = ((int)_config.ShipList.ShipCategories & (1 << type)) != 0;\r
-            checkBoxSTypeAll.Checked = _config.ShipList.ShipCategories == ShipCategory.All;\r
-            checkBoxSTypeDetails.Checked = _config.ShipList.ShipType;\r
+                _shipTypeCheckBoxes[type].Checked = ((int)_settings.ShipCategories & (1 << type)) != 0;\r
+            checkBoxSTypeAll.Checked = _settings.ShipCategories == ShipCategory.All;\r
+            checkBoxSTypeDetails.Checked = _settings.ShipType;\r
         }\r
 \r
         private void ListForm_FormClosing(object sender, FormClosingEventArgs e)\r
         {\r
             e.Cancel = true;\r
-            if (!Visible) // 非表示のときは保存すべき情報がないのでスキップする\r
-                return;\r
-            var config = _config.ShipList;\r
+            Hide();\r
+        }\r
+\r
+        public void SaveConfig()\r
+        {\r
+            if (_isMaster)\r
+            {\r
+                SaveMasterState();\r
+            }\r
+            else\r
+            {\r
+                SaveSlaveState();\r
+            }\r
+        }\r
+\r
+        private void SaveMasterState()\r
+        {\r
             StoreShipGroupToConfig();\r
+            var config = _config.ShipList;\r
+            config.Visible = Visible && WindowState == FormWindowState.Normal;\r
+            _settings.SetToShipListConfig(config);\r
+            if (!Visible)\r
+                return;\r
+            SaveBounds(config); // 最小化時は以前のサイズを記録する\r
+        }\r
+\r
+        private void SaveSlaveState()\r
+        {\r
+            if (!Visible)\r
+                return;\r
+            if (WindowState != FormWindowState.Normal) // 最小化時は次回復旧しない\r
+                return;\r
+            var config = new ShipListConfig {Visible = true};\r
+            _settings.SetToShipListConfig(config);\r
+            _config.ListFormGroup.Add(config);\r
+            SaveBounds(config);\r
+        }\r
+\r
+        private void SaveBounds(ShipListConfig config)\r
+        {\r
             var bounds = WindowState == FormWindowState.Normal ? Bounds : RestoreBounds;\r
             config.Location = bounds.Location;\r
             config.Size = bounds.Size;\r
-            config.Mode = (string)comboBoxGroup.SelectedItem;\r
-            Hide();\r
         }\r
 \r
         public void ChangeWindowState(FormWindowState newState)\r
@@ -283,6 +394,8 @@ namespace KancolleSniffer
 \r
         private void ListForm_Activated(object sender, EventArgs e)\r
         {\r
+            if (!_isMaster)\r
+                return;\r
             if (_suppressActivate.Check())\r
                 return;\r
             if (WindowState == FormWindowState.Minimized)\r
@@ -303,7 +416,7 @@ namespace KancolleSniffer
             var all = _sniffer.ShipList.Select(s => s.Id).ToArray();\r
             var group = _config.ShipList.ShipGroup;\r
             group.Clear();\r
-            for (var i = 0; i < ShipListPanel.GroupCount; i++)\r
+            for (var i = 0; i < GroupConfigLabels.GroupCount; i++)\r
             {\r
                 if (all.Length > 0)\r
                     shipListPanel.GroupSettings[i].IntersectWith(all);\r
@@ -334,17 +447,16 @@ namespace KancolleSniffer
 \r
         private void comboBoxGroup_SelectedIndexChanged(object sender, EventArgs e)\r
         {\r
+            _settings.Mode = comboBoxGroup.Text;\r
             UpdateList();\r
             SetActiveControl();\r
-            copyToolStripMenuItem.Enabled = InShipStatus | InItemList;\r
             if (!(InShipStatus || InGroupConfig || InRepairList))\r
                 SetPanelSTypeState(false);\r
         }\r
 \r
         private void ListForm_KeyPress(object sender, KeyPressEventArgs e)\r
         {\r
-            var g = Array.FindIndex(new[] {'Z', 'A', 'B', 'C', 'D', 'G', 'R', 'W', 'X', 'Y', 'S', 'I'},\r
-                x => x == char.ToUpper(e.KeyChar));\r
+            var g = Array.FindIndex(PanelKeys, x => x == char.ToUpper(e.KeyChar));\r
             if (g == -1)\r
                 return;\r
             comboBoxGroup.SelectedIndex = g;\r
@@ -372,12 +484,17 @@ namespace KancolleSniffer
             }\r
         }\r
 \r
-        private void copyToolStripMenuItem_Click(object sender, EventArgs e)\r
+        private void itemCsvToolStripMenuItem_Click(object sender, EventArgs e)\r
         {\r
             Clipboard.SetText(TextGenerator.GenerateItemList(_sniffer.ItemList));\r
         }\r
 \r
-        private void textToolStripMenuItem_Click(object sender, EventArgs e)\r
+        private void kantaiBunsekiToolStripMenuItem_Click(object sender, EventArgs e)\r
+        {\r
+            Clipboard.SetText(TextGenerator.GenerateKantaiBunsekiItemList(_sniffer.ItemList));\r
+        }\r
+\r
+        private void fleetTextToolStripMenuItem_Click(object sender, EventArgs e)\r
         {\r
             Clipboard.SetText(TextGenerator.GenerateFleetData(_sniffer));\r
         }\r
@@ -389,17 +506,16 @@ namespace KancolleSniffer
 \r
         private void labelHeaderCond_Click(object sender, EventArgs e)\r
         {\r
-            var sl = _config.ShipList;\r
-            switch (sl.SortOrder)\r
+            switch (_settings.SortOrder)\r
             {\r
                 case SortOrder.CondAscend:\r
-                    sl.SortOrder = SortOrder.CondDescend;\r
+                    _settings.SortOrder = SortOrder.CondDescend;\r
                     break;\r
                 case SortOrder.CondDescend:\r
-                    sl.SortOrder = SortOrder.None;\r
+                    _settings.SortOrder = SortOrder.None;\r
                     break;\r
                 default:\r
-                    sl.SortOrder = SortOrder.CondAscend;\r
+                    _settings.SortOrder = SortOrder.CondAscend;\r
                     break;\r
             }\r
             UpdateList();\r
@@ -407,33 +523,30 @@ namespace KancolleSniffer
 \r
         private void labelHeaderExp_Click(object sender, EventArgs e)\r
         {\r
-            var sl = _config.ShipList;\r
-            switch (sl.SortOrder)\r
+            switch (_settings.SortOrder)\r
             {\r
                 case SortOrder.ExpToNextAscend:\r
-                    sl.SortOrder = SortOrder.ExpToNextDescend;\r
+                    _settings.SortOrder = SortOrder.ExpToNextDescend;\r
                     break;\r
                 case SortOrder.ExpToNextDescend:\r
-                    sl.SortOrder = SortOrder.None;\r
+                    _settings.SortOrder = SortOrder.None;\r
                     break;\r
                 default:\r
-                    sl.SortOrder = SortOrder.ExpToNextAscend;\r
+                    _settings.SortOrder = SortOrder.ExpToNextAscend;\r
                     break;\r
             }\r
             UpdateList();\r
         }\r
 \r
-        private void csvToolStripMenuItem_Click(object sender, EventArgs e)\r
+        private void shipCsvToolStripMenuItem_Click(object sender, EventArgs e)\r
         {\r
             Clipboard.SetText(TextGenerator.GenerateShipList(shipListPanel.CurrentShipList));\r
         }\r
 \r
-        // ReSharper disable IdentifierTypo\r
         private void kantaiSarashiToolStripMenuItem_Click(object sender, EventArgs e)\r
         {\r
             Clipboard.SetText(TextGenerator.GenerateKantaiSarashiData(shipListPanel.CurrentShipList));\r
         }\r
-        // ReSharper enable IdentifierTypo\r
 \r
         private void labelFleet_Click(object sender, EventArgs e)\r
         {\r
@@ -447,7 +560,7 @@ namespace KancolleSniffer
 \r
         private void ToggleHpPercent()\r
         {\r
-            _config.ShipList.ShowHpInPercent = !_config.ShipList.ShowHpInPercent;\r
+            _settings.ShowHpInPercent = !_settings.ShowHpInPercent;\r
             shipListPanel.ToggleHpPercent();\r
             battleResultPanel.ToggleHpPercent();\r
         }\r
@@ -459,7 +572,7 @@ namespace KancolleSniffer
 \r
         private void checkBoxSType_Click(object sender, EventArgs e)\r
         {\r
-            _config.ShipList.ShipCategories = SelectedShipTypes;\r
+            _settings.ShipCategories = SelectedShipTypes;\r
             UpdateList();\r
             SetActiveControl();\r
         }\r
@@ -482,12 +595,14 @@ namespace KancolleSniffer
         private void SetPanelSTypeState(bool visible)\r
         {\r
             panelSType.Visible = visible;\r
-            labelSTypeButton.BackColor = visible ? CustomColors.ActiveButtonColor : DefaultBackColor;\r
+            if (visible)\r
+                panelSType.BringToFront();\r
+            dropDownButtonSType.BackColor = visible ? CustomColors.ActiveButtonColor : DefaultBackColor;\r
         }\r
 \r
         private void checkBoxSTypeDetails_Click(object sender, EventArgs e)\r
         {\r
-            _config.ShipList.ShipType = checkBoxSTypeDetails.Checked;\r
+            _settings.ShipType = checkBoxSTypeDetails.Checked;\r
             UpdateList();\r
             SetActiveControl();\r
         }\r