OSDN Git Service

#keyPathが利用可能な部分はそれを利用するようにした
[kcd/KCD.git] / KCD / AirBaseWindowController.swift
1 //
2 //  AirBaseWindowController.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2016/12/22.
6 //  Copyright © 2016年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 final class AirBaseWindowController: NSWindowController {
12     
13     @objc let managedObjectContext = ServerDataStore.default.context
14     
15     @IBOutlet var areaMatrix: NSMatrix!
16     @IBOutlet var squadronTab: NSSegmentedControl!
17     @IBOutlet var planesTable: NSTableView!
18     @IBOutlet var airBaseController: NSArrayController!
19     
20     override var windowNibName: NSNib.Name {
21         
22         return .nibName(instanceOf: self)
23     }
24     
25     @objc dynamic var areaId: Int = 0 {
26         
27         didSet {
28             updatePredicate()
29             updatePlaneSegment()
30         }
31     }
32     
33     @objc dynamic var rId: Int = 1 {
34         
35         didSet {
36             updatePredicate()
37             updatePlaneSegment()
38         }
39     }
40     
41     private var areas: [Int] {
42         
43         guard let content = airBaseController.content as? [AirBase] else { return [] }
44         
45         return content
46             .flatMap { $0.area_id }
47             .unique()
48             .sorted(by: <)
49     }
50     
51     override func windowDidLoad() {
52         
53         super.windowDidLoad()
54         
55         airBaseController.addObserver(self, forKeyPath: #keyPath(airBaseController.content), context: nil)
56     }
57     
58     override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
59         
60         guard keyPath == #keyPath(airBaseController.content) else {
61             
62             super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
63             return
64         }
65         
66         updateAreaRadio()
67         updatePlaneSegment()
68         
69         if areaId == 0 {
70             
71             areaId = areas.first ?? 0
72             updatePredicate()
73         }
74     }
75     
76     private func updateAreaRadio() {
77         
78         //  更新の必要性チェック
79         let areas = self.areas
80         let currentTags = areaMatrix.cells.map { $0.tag }
81         
82         if currentTags == areas { return }
83         
84         // 最初の設定以外でareasが空の場合は処理をしない
85         if areas.isEmpty, areaId != 0 { return }
86         
87         let cellCount = areaMatrix.numberOfRows * areaMatrix.numberOfColumns
88         if areas.count != cellCount {
89             
90             let diff = areas.count - areaMatrix.numberOfColumns
91             while areas.count != areaMatrix.numberOfColumns {
92                 
93                 if diff < 0 {
94                     
95                     areaMatrix.removeColumn(0)
96                     
97                 } else {
98                     
99                     areaMatrix.addColumn()
100                 }
101             }
102         }
103         
104         if areaMatrix.numberOfColumns == 0 {
105             
106             areaMatrix.addColumn()
107             let areaCell = areaMatrix.cell(atRow: 0, column: 0)
108             areaCell?.title = ""
109             areaCell?.tag = -10_000
110             
111             areaMatrix.isEnabled = false
112             
113         } else {
114             
115             areaMatrix.isEnabled = true
116         }
117         
118         let t = AreaNameTransformer()
119         areas.enumerated().forEach {
120             
121             let areaCell = areaMatrix.cell(atRow: 0, column: $0.offset)
122             areaCell?.title = t.transformedValue($0.element) as? String ?? String($0.element)
123             areaCell?.tag = $0.element
124         }
125     }
126     
127     private func updatePlaneSegment() {
128         
129         guard let content = airBaseController.content as? [AirBase] else { return }
130         
131         let area = NSCountedSet()
132         content.forEach { area.add($0.area_id) }
133         let count = area.count(for: areaId)
134         (0...2).forEach { squadronTab.setEnabled($0 < count, forSegment: $0) }
135     }
136     
137     private func updatePredicate() {
138         
139         airBaseController.filterPredicate = NSPredicate(format: "area_id = %ld AND rid = %ld", areaId, rId)
140         airBaseController.setSelectionIndex(0)
141         planesTable.deselectAll(nil)
142     }
143 }
144
145 extension AirBaseWindowController: NSTableViewDelegate {
146     
147     func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
148         
149         guard let identifier = tableColumn?.identifier else { return nil }
150         
151         return tableView.makeView(withIdentifier: identifier, owner: nil)
152     }
153     
154     func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
155         
156         return false
157     }
158 }