1 // Copyright (C) 2014, 2015 Kazuhiro Fujieda <fujieda@users.osdn.me>
\r
3 // Licensed under the Apache License, Version 2.0 (the "License");
\r
4 // you may not use this file except in compliance with the License.
\r
5 // You may obtain a copy of the License at
\r
7 // http://www.apache.org/licenses/LICENSE-2.0
\r
9 // Unless required by applicable law or agreed to in writing, software
\r
10 // distributed under the License is distributed on an "AS IS" BASIS,
\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
12 // See the License for the specific language governing permissions and
\r
13 // limitations under the License.
\r
16 using System.Collections;
\r
17 using System.Collections.Generic;
\r
19 using System.Runtime.InteropServices;
\r
20 using System.Windows.Forms;
\r
22 namespace KancolleSniffer
\r
24 public class ItemTreeView : DbTreeView
\r
26 private ItemStatus[] _prevItemList;
\r
28 public void SetNodes(ItemStatus[] itemList)
\r
30 if (_prevItemList != null && _prevItemList.SequenceEqual(itemList, new ItemStatusComparer()))
\r
32 _prevItemList = itemList.Select(CloneItemStatus).ToArray();
\r
33 SetNodes(CreateItemNodes(itemList));
\r
36 private TreeNode CreateItemNodes(IEnumerable<ItemStatus> itemList)
\r
38 var grouped = from byItem in (from item in itemList
\r
39 where item.Spec.Id != -1
\r
40 orderby item.Spec.Type, item.Spec.Id, item.Alv, item.Level descending
\r
41 group item by new {item.Spec.Id, item.Alv, item.Level}
\r
45 let ship = item.Ship
\r
46 orderby ship.Level descending, ship.Spec.SortNo
\r
47 group item by item.Ship.Id)
\r
48 group byShip by grp.Key)
\r
49 group byItem by byItem.First().First().Spec.Type;
\r
51 var root = new TreeNode();
\r
52 foreach (var byType in grouped)
\r
54 var typeName = byType.First().First().First().Spec.TypeName;
\r
55 var typeNode = new TreeNode();
\r
56 typeNode.Name = typeNode.Text = typeName;
\r
57 root.Nodes.Add(typeNode);
\r
58 foreach (var byItem in byType)
\r
60 var item = byItem.First().First();
\r
61 var itemNode = new TreeNode();
\r
62 itemNode.Name = itemNode.Text = item.Spec.Name +
\r
63 (item.Alv == 0 ? "" : "+" + item.Alv) +
\r
64 (item.Level == 0 ? "" : "★" + item.Level);
\r
65 typeNode.Nodes.Add(itemNode);
\r
66 foreach (var byShip in byItem)
\r
68 var ship = byShip.First().Ship;
\r
69 var name = byShip.Key == -1
\r
70 ? "未装備x" + byShip.Count()
\r
71 : (ship.Fleet != -1 ? ship.Fleet + 1 + " " : "") +
\r
72 ship.Name + "Lv" + ship.Level + "×" + byShip.Count();
\r
73 itemNode.Nodes.Add(name, name);
\r
80 private ItemStatus CloneItemStatus(ItemStatus org)
\r
82 return new ItemStatus
\r
86 Ship = new ShipStatus {Id = org.Ship.Id, Fleet = org.Ship.Fleet}
\r
90 private class ItemStatusComparer : IEqualityComparer<ItemStatus>
\r
92 public bool Equals(ItemStatus x, ItemStatus y)
\r
93 => x.Level == y.Level && x.Spec == y.Spec && x.Ship.Id == y.Ship.Id && x.Ship.Fleet == y.Ship.Fleet;
\r
95 public int GetHashCode(ItemStatus obj) => obj.Level + obj.Spec.GetHashCode() + obj.Ship.GetHashCode();
\r
98 [DllImport("user32.dll")]
\r
99 private static extern int GetScrollPos(IntPtr hWnd, int nBar);
\r
101 [DllImport("user32.dll")]
\r
102 private static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);
\r
104 private void SetNodes(TreeNode root)
\r
106 var y = GetScrollPos(Handle, 1);
\r
108 var save = SaveTreeViewState(Nodes);
\r
110 foreach (TreeNode child in root.Nodes)
\r
112 RestoreTreeViewState(Nodes, save.Nodes);
\r
114 SetScrollPos(Handle, 1, y, true);
\r
117 private TreeNode SaveTreeViewState(IEnumerable nodes)
\r
119 var result = new TreeNode();
\r
120 foreach (TreeNode child in nodes)
\r
122 var copy = SaveTreeViewState(child.Nodes);
\r
123 if (child.IsExpanded)
\r
125 copy.Name = child.Name;
\r
126 result.Nodes.Add(copy);
\r
131 private void RestoreTreeViewState(TreeNodeCollection dst, TreeNodeCollection src)
\r
133 foreach (TreeNode d in dst)
\r
135 var s = src[d.Name];
\r
140 RestoreTreeViewState(d.Nodes, s.Nodes);
\r