OSDN Git Service

keyPathsForValuesAffectingValue(forKey:)に集約した
[kcd/KCD.git] / KCD / UpgradableShipsWindowController.swift
1 //
2 //  UpgradableShipsWindowController.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2016/12/18.
6 //  Copyright © 2016年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 private extension Selector {
12     
13     static let showHideShip = #selector(UpgradableShipsWindowController.showHideShip(_:))
14 }
15
16 final class UpgradableShipsWindowController: NSWindowController {
17     
18     @objc let managedObjectContext = ServerDataStore.default.context
19     
20     private static var excludeShiIDsCache: [Int] = []
21     
22     class func isExcludeShipID(_ shipID: Int) -> Bool {
23         
24         return excludeShiIDsCache.contains(shipID)
25     }
26     
27     @objc override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
28         
29         switch key {
30             
31         case #keyPath(filterPredicate): return [#keyPath(showLevelOneShipInUpgradableList), #keyPath(showsExcludedShipInUpgradableList)]
32         
33         default: return []
34         }
35     }
36     
37     private var excludeShiIDsCache: [Int] {
38         
39         get { return UpgradableShipsWindowController.excludeShiIDsCache }
40         set { UpgradableShipsWindowController.excludeShiIDsCache = newValue }
41     }
42     
43     private func isExcludeShipID(_ shipID: Int) -> Bool {
44         
45         return excludeShiIDsCache.contains(shipID)
46     }
47     
48     
49     @IBOutlet var contextualMenu: NSMenu!
50     @IBOutlet var tableView: NSTableView!
51     @IBOutlet var shipsController: NSArrayController!
52     
53     override var windowNibName: NSNib.Name {
54         
55         return .nibName(instanceOf: self)
56     }
57     
58     @objc dynamic var filterPredicate: NSPredicate? {
59         
60         var filterPredicate: NSPredicate?
61         var excludeShip: NSPredicate?
62         
63         if showLevelOneShipInUpgradableList == false {
64             
65             filterPredicate = NSPredicate(format: "lv != 1")
66         }
67         
68         if showsExcludedShipInUpgradableList == false,
69             excludeShiIDs.count != 0 {
70             
71             excludeShip = NSPredicate(format: "NOT id IN %@", excludeShiIDs)
72         }
73         
74         if let filterPredicate = filterPredicate,
75             let excludeShip = excludeShip {
76             
77             return NSCompoundPredicate(andPredicateWithSubpredicates: [filterPredicate, excludeShip])
78         }
79         
80         if let filterPredicate = filterPredicate { return filterPredicate }
81         if let excludeShip = excludeShip { return excludeShip }
82         
83         return nil
84     }
85     
86     @objc var showLevelOneShipInUpgradableList: Bool {
87         
88         get { return UserDefaults.standard[.showLevelOneShipInUpgradableList] }
89         set { UserDefaults.standard[.showLevelOneShipInUpgradableList] = newValue }
90     }
91     
92     @objc var showsExcludedShipInUpgradableList: Bool {
93         
94         get { return UserDefaults.standard[.showsExcludedShipInUpgradableList] }
95         set { UserDefaults.standard[.showsExcludedShipInUpgradableList] = newValue }
96     }
97     
98     var excludeShiIDs: [Int] {
99         
100         get { return (NSArray(contentsOf: excludeShipIDsSaveURL) as? [Int]) ?? [] }
101         set {
102             notifyChangeValue(forKey: #keyPath(filterPredicate)) {
103                 
104                 (newValue as NSArray).write(to: excludeShipIDsSaveURL, atomically: true)
105                 UpgradableShipsWindowController.excludeShiIDsCache = newValue
106             }
107         }
108     }
109     
110     private var excludeShipIDsSaveURL: URL {
111         
112         return ApplicationDirecrories.support.appendingPathComponent("ExcludeShipIDs")
113     }
114     
115     override func windowDidLoad() {
116         
117         super.windowDidLoad()
118         
119         excludeShiIDsCache = excludeShiIDs
120     }
121     
122     private func includeShip(shipID: Int) {
123         
124         var array = excludeShiIDs
125         
126         guard let index = array.index(of: shipID) else { return }
127         
128         array.remove(at: index)
129         excludeShiIDs = array
130     }
131     
132     private func excludeShip(shipID: Int) {
133         
134         var array = excludeShiIDs
135         array.append(shipID)
136         excludeShiIDs = array
137     }
138     
139     @IBAction func showHideShip(_ sender: AnyObject?) {
140         
141         let row = tableView.clickedRow
142         
143         guard let ships = shipsController.arrangedObjects as? [Ship] else { return }
144         guard case 0..<ships.count = row else { return }
145         
146         let shipID = ships[row].id
147         if isExcludeShipID(shipID) {
148             
149             includeShip(shipID: shipID)
150             
151         } else {
152             
153             excludeShip(shipID: shipID)
154         }
155     }
156     
157     override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
158         
159         if menuItem.action == .showHideShip {
160             
161             let row = tableView.clickedRow
162             
163             guard let ships = shipsController.arrangedObjects as? [Ship] else { return false }
164             guard case 0..<ships.count = row else { return false }
165             
166             let shipID = ships[row].id
167             if isExcludeShipID(shipID) {
168                 
169                 menuItem.title = LocalizedStrings.showKanmusu.string
170                 
171             } else {
172                 
173                 menuItem.title = LocalizedStrings.hideKanmusu.string
174             }
175             
176             return true
177         }
178         
179         return false
180     }
181 }