OSDN Git Service

questlistがすべての任務を返す仕様変更に対応する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / ListForm.cs
index e306441..0068758 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
@@ -26,9 +27,61 @@ namespace KancolleSniffer
     {\r
         private readonly Sniffer _sniffer;\r
         private readonly Config _config;\r
+        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
@@ -41,11 +94,14 @@ namespace KancolleSniffer
             Repair\r
         }\r
 \r
-        public ListForm(Sniffer sniffer, Config config)\r
+        public ListForm(MainForm main)\r
         {\r
             InitializeComponent();\r
-            _sniffer = sniffer;\r
-            _config = config;\r
+            IsMaster = false;\r
+            _main = main;\r
+            _sniffer = main.Sniffer;\r
+            _config = main.Config;\r
+            _suppressActivate = main.SuppressActivate;\r
             _shipTypeCheckBoxes = new[]\r
             {\r
                 checkBoxSTypeBattleShip,\r
@@ -65,33 +121,10 @@ namespace KancolleSniffer
             swipe.AddPanel(fleetPanel);\r
         }\r
 \r
-        /// <summary>\r
-        /// パネルのz-orderがくるうのを避ける\r
-        /// https://stackoverflow.com/a/5777090/1429506\r
-        /// </summary>\r
-        private void ListForm_Shown(object sender, EventArgs e)\r
-        {\r
-            // ReSharper disable once NotAccessedVariable\r
-            IntPtr handle;\r
-            foreach (Control panel in Controls)\r
-                // ReSharper disable once RedundantAssignment\r
-                handle = panel.Handle;\r
-        }\r
-\r
         public void UpdateList()\r
         {\r
-            panelItemHeader.Visible = InItemList || InAntiAir || InBattleResult || InMiscText;\r
-            panelGroupHeader.Visible = InGroupConfig;\r
-            panelRepairHeader.Visible = InRepairList;\r
-            panelFleetHeader.Visible = InFleetInfo;\r
-            // SwipeScrollifyが誤作動するのでEnabledも切り替える\r
-            shipListPanel.Visible = shipListPanel.Enabled = InShipStatus || InGroupConfig || InRepairList;\r
-            itemTreeView.Visible = itemTreeView.Enabled = InItemList;\r
-            fleetPanel.Visible = fleetPanel.Enabled = InFleetInfo;\r
-            antiAirPanel.Visible = antiAirPanel.Enabled = InAntiAir;\r
-            airBattleResultPanel.Visible = airBattleResultPanel.Enabled =\r
-                battleResultPanel.Visible = battleResultPanel.Enabled = InBattleResult;\r
-            richTextBoxMiscText.Visible = InMiscText;\r
+            SetHeaderVisibility();\r
+            SetPanelVisibility();\r
             if (InItemList)\r
             {\r
                 itemTreeView.SetNodes(_sniffer.ItemList);\r
@@ -108,10 +141,10 @@ namespace KancolleSniffer
             {\r
                 richTextBoxMiscText.Text = _sniffer.MiscText;\r
             }\r
-            else\r
+            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
@@ -121,16 +154,70 @@ namespace KancolleSniffer
             }\r
         }\r
 \r
+        private void SetHeaderVisibility()\r
+        {\r
+            static void Set(Control header, bool visible)\r
+            {\r
+                header.Visible = visible;\r
+                if (visible)\r
+                    header.BringToFront();\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
+            static void Set(Control panel, bool visible)\r
+            {\r
+                // SwipeScrollifyが誤作動するのでEnabledも切り替える\r
+                panel.Visible = panel.Enabled = visible;\r
+            }\r
+\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
         {\r
             airBattleResultPanel.ShowResultAutomatic = (_config.Spoilers & Spoiler.AirBattleResult) != 0;\r
-            airBattleResultPanel.SetResult(_sniffer.Battle.AirBattleResults);\r
+            airBattleResultPanel.SetResult(_sniffer);\r
         }\r
 \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
@@ -141,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
@@ -166,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 ShipListForm_Load(object sender, EventArgs e)\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
@@ -207,37 +295,120 @@ 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 ShipListForm_FormClosing(object sender, FormClosingEventArgs e)\r
+        private void ListForm_FormClosing(object sender, FormClosingEventArgs e)\r
         {\r
             e.Cancel = true;\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
-            var config = _config.ShipList;\r
-            StoreShipGroupToConfig();\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
-            if (e.CloseReason != CloseReason.FormOwnerClosing)\r
+        }\r
+\r
+        public void ChangeWindowState(FormWindowState newState)\r
+        {\r
+            if (!Visible)\r
+                return;\r
+            if (newState == FormWindowState.Minimized)\r
             {\r
-                Hide();\r
-                _config.Save();\r
+                if (WindowState == FormWindowState.Normal)\r
+                    WindowState = FormWindowState.Minimized;\r
+                if (_config.HideOnMinimized)\r
+                    ShowInTaskbar = false;\r
             }\r
+            else\r
+            {\r
+                if (WindowState == FormWindowState.Minimized)\r
+                {\r
+                    System.Windows.Forms.Application.DoEvents();\r
+                    if (_config.HideOnMinimized)\r
+                        ShowInTaskbar = true;\r
+                    WindowState = FormWindowState.Normal;\r
+                }\r
+            }\r
+        }\r
+\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
+                return;\r
+            RaiseBothWindows();\r
+        }\r
+\r
+        private void RaiseBothWindows()\r
+        {\r
+            _main.Owner = null;\r
+            Owner = _main;\r
+            BringToFront();\r
+            Owner = null;\r
         }\r
 \r
         private void StoreShipGroupToConfig()\r
@@ -245,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
@@ -276,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 ShipListForm_KeyPress(object sender, KeyPressEventArgs e)\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
@@ -314,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
@@ -331,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
@@ -349,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
@@ -389,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
@@ -401,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
@@ -424,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