OSDN Git Service

swiftlint 'comma' の警告を修正
[kcd/KCD.git] / KCD / ShipViewController.swift
1 //
2 //  ShipViewController.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2016/12/25.
6 //  Copyright © 2016年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 fileprivate enum ViewType: Int {
12     case exp
13     case power
14     case power2
15     case power3
16 }
17
18 class ShipViewController: MainTabVIewItemViewController {
19     let managedObjectContext = ServerDataStore.default.managedObjectContext
20     
21     deinit {
22         NotificationCenter.default.removeObserver(self)
23     }
24     
25     @IBOutlet var shipController: NSArrayController!
26     @IBOutlet var expTableView: NSScrollView!
27     @IBOutlet var powerTableView: NSScrollView!
28     @IBOutlet var power2TableView: NSScrollView!
29     @IBOutlet var power3TableView: NSScrollView!
30     @IBOutlet weak var standardDeviationField: NSTextField!
31     
32     override var nibName: String! {
33         return "ShipViewController"
34     }
35     override var hasShipTypeSelector: Bool { return true }
36     override var selectedShipType: ShipType {
37         didSet {
38             shipController.filterPredicate = predicate(for: selectedShipType)
39             shipController.rearrangeObjects()
40         }
41     }
42     
43     var standardDeviation: Double {
44         guard let ships = shipController.arrangedObjects as? [Ship],
45             !ships.isEmpty,
46             let avg = shipController.value(forKeyPath: "arrangedObjects.@avg.lv") as? Double
47             else { return 0.0 }
48         let total = ships.reduce(0.0) {
49             let delta = Double($1.lv) - avg
50             return $0 + delta * delta
51         }
52         return sqrt(total / Double(ships.count))
53     }
54     
55     fileprivate weak var currentTableView: NSView?
56     
57     override func viewDidLoad() {
58         super.viewDidLoad()
59         
60         currentTableView = expTableView
61         
62         try! shipController.fetch(with: nil, merge: true)
63         shipController.sortDescriptors = UserDefaults.standard.shipviewSortDescriptors
64         shipController.addObserver(self, forKeyPath: NSSortDescriptorsBinding, context: nil)
65         shipController.addObserver(self, forKeyPath: "arrangedObjects", context: nil)
66         
67         let tableViews = [expTableView, powerTableView, power2TableView, power3TableView]
68         tableViews
69             .forEach {
70                 NotificationCenter.default
71                     .addObserver(forName: .NSScrollViewDidEndLiveScroll, object: $0, queue: nil) { notification in
72                         guard let target = notification.object as? NSScrollView else { return }
73                         let visibleRect = target.documentVisibleRect
74                         tableViews
75                             .filter { $0 != target }
76                             .forEach { $0?.documentView?.scrollToVisible(visibleRect) }
77                 }
78         }
79         #if DEBUG
80             standardDeviationField.isHidden = false
81         #endif
82     }
83     override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
84         if keyPath == NSSortDescriptorsBinding {
85             UserDefaults.standard.shipviewSortDescriptors = shipController.sortDescriptors
86             return
87         }
88         if keyPath == "arrangedObjects" {
89             willChangeValue(forKey: "standardDeviation")
90             didChangeValue(forKey: "standardDeviation")
91             return
92         }
93         
94         super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
95     }
96     
97     fileprivate func showView(with type: ViewType) {
98         let newSelection: NSView = {
99             switch type {
100             case .exp:
101                 return expTableView
102             case .power:
103                 return powerTableView
104             case .power2:
105                 return power2TableView
106             case .power3:
107                 return power3TableView
108             }
109         }()
110         if currentTableView == newSelection { return }
111         guard let tableView = currentTableView
112             else { return }
113         newSelection.frame = tableView.frame
114         newSelection.autoresizingMask = tableView.autoresizingMask
115         view.replaceSubview(tableView, with: newSelection)
116         view.window?.makeFirstResponder(newSelection)
117         currentTableView = newSelection
118     }
119     
120     private func tag(_ sender: AnyObject?) -> Int {
121         guard let sender = sender
122             else { return -1 }
123         if let control = sender as? NSSegmentedControl,
124             let cell = sender.cell as? NSSegmentedCell {
125             return cell.tag(forSegment: control.selectedSegment)
126         }
127         if let control = sender as? NSControl {
128             return control.tag
129         }
130         return -1
131     }
132     @IBAction func changeView(_ sender: AnyObject?) {
133         ViewType(rawValue: tag(sender)).map { showView(with: $0) }
134     }
135 }
136
137 extension ShipViewController: NSTableViewDelegate {
138     func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
139         guard let identifier = tableColumn?.identifier else { return nil }
140         return tableView.make(withIdentifier: identifier, owner: nil)
141     }
142 }