2 // ShipViewController.swift
5 // Created by Hori,Masaki on 2016/12/25.
6 // Copyright © 2016年 Hori,Masaki. All rights reserved.
11 private enum ViewType: Int {
19 final class ShipViewController: MainTabVIewItemViewController {
21 @objc let managedObjectContext = ServerDataStore.default.context
25 NotificationCenter.default.removeObserver(self)
28 @IBOutlet var shipController: NSArrayController!
29 @IBOutlet var expTableView: NSScrollView!
30 @IBOutlet var powerTableView: NSScrollView!
31 @IBOutlet var power2TableView: NSScrollView!
32 @IBOutlet var power3TableView: NSScrollView!
33 @IBOutlet weak var standardDeviationField: NSTextField!
35 private var sortDescriptorsObservation: NSKeyValueObservation?
36 private var arrangedObjectsObservation: NSKeyValueObservation?
38 override var nibName: NSNib.Name {
40 return .nibName(instanceOf: self)
43 override var hasShipTypeSelector: Bool { return true }
44 override var selectedShipType: ShipTabType {
47 shipController.filterPredicate = shipTypePredicte
48 shipController.rearrangeObjects()
52 @objc var standardDeviation: Double {
54 guard let ships = shipController.arrangedObjects as? [Ship], !ships.isEmpty else { return 0.0 }
55 guard let avg = shipController.value(forKeyPath: "arrangedObjects.@avg.lv") as? Double else { return 0.0 }
57 let total = ships.reduce(0.0) {
59 let delta = Double($1.lv) - avg
61 return $0 + delta * delta
64 return sqrt(total / Double(ships.count))
67 private weak var currentTableView: NSView?
69 override func viewDidLoad() {
73 currentTableView = expTableView
77 try shipController.fetch(with: nil, merge: true)
81 fatalError("ShipViewController: can not fetch. \(error)")
85 shipController.sortDescriptors = UserDefaults.standard[.shipviewSortDescriptors]
87 sortDescriptorsObservation = shipController.observe(\NSArrayController.sortDescriptors) { [weak self] _, _ in
89 UserDefaults.standard[.shipviewSortDescriptors] = self?.shipController.sortDescriptors ?? []
91 arrangedObjectsObservation = shipController.observe(\NSArrayController.arrangedObjects) { [weak self] _, _ in
93 self?.notifyChangeValue(forKey: #keyPath(standardDeviation))
96 let tableViews = [expTableView, powerTableView, power2TableView, power3TableView]
100 NotificationCenter.default
101 .addObserver(forName: NSScrollView.didEndLiveScrollNotification, object: $0, queue: nil) {
103 guard let target = $0.object as? NSScrollView else { return }
105 let visibleRect = target.documentVisibleRect
107 .filter { $0 != target }
108 .forEach { $0?.documentView?.scrollToVisible(visibleRect) }
112 standardDeviationField.isHidden = false
116 private func showView(with type: ViewType) {
118 let newSelection: NSView = {
121 case .exp: return expTableView
122 case .power: return powerTableView
123 case .power2: return power2TableView
124 case .power3: return power3TableView
128 if currentTableView == newSelection { return }
130 guard let tableView = currentTableView else { return }
132 newSelection.frame = tableView.frame
133 newSelection.autoresizingMask = tableView.autoresizingMask
134 view.replaceSubview(tableView, with: newSelection)
135 view.window?.makeFirstResponder(newSelection)
136 currentTableView = newSelection
139 private func tag(_ sender: AnyObject?) -> Int {
143 case let segmented as NSSegmentedControl:
144 let cell = segmented.cell as? NSSegmentedCell
146 return cell?.tag(forSegment: segmented.selectedSegment) ?? -1
148 case let control as NSControl:
156 @IBAction func changeView(_ sender: AnyObject?) {
158 ViewType(rawValue: tag(sender)).map(showView)
162 extension ShipViewController: NSTableViewDelegate {
164 func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
166 guard let identifier = tableColumn?.identifier else { return nil }
168 return tableView.makeView(withIdentifier: identifier, owner: nil)