OSDN Git Service

複数回使用されていないセレクタをstatic letから外した
[kcd/KCD.git] / KCD / ScreenshotEditorViewController.swift
1 //
2 //  ScreenshotEditorViewController.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2016/12/29.
6 //  Copyright © 2016年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 private struct EditedImage {
12     
13     var editedImage: NSImage
14     var url: URL
15     
16     init(image: NSImage, url: URL) {
17         
18         editedImage = image
19         self.url = url
20     }
21 }
22
23 final class TrimRectInformation: NSObject {
24     
25     @objc private(set) var name: String
26     private(set) var rect: NSRect
27     
28     fileprivate init(name: String, rect: NSRect) {
29         
30         self.name = name
31         self.rect = rect
32     }
33 }
34
35 final class ScreenshotEditorViewController: BridgeViewController {
36     
37     @objc let trimInfo: [TrimRectInformation]
38     
39     override init(nibName: NSNib.Name?, bundle: Bundle?) {
40         
41         trimInfo = [
42             TrimRectInformation(name: "Status", rect: NSRect(x: 328, y: 13, width: 470, height: 365)),
43             TrimRectInformation(name: "List", rect: NSRect(x: 362, y: 15, width: 438, height: 368)),
44             TrimRectInformation(name: "AirplaneBase", rect: NSRect(x: 575, y: 13, width: 225, height: 358))
45         ]
46         currentTrimInfo = trimInfo[0]
47         
48         super.init(nibName: ScreenshotEditorViewController.nibName, bundle: nil)
49     }
50     
51     required init?(coder: NSCoder) {
52         
53         fatalError("init(coder:) has not been implemented")
54     }
55     
56     
57     @IBOutlet weak var tiledImageView: TiledImageView!
58     @IBOutlet weak var doneButton: NSButton!
59     
60     @objc var columnCount: Int {
61         
62         get { return tiledImageView.columnCount }
63         set {
64             tiledImageView.columnCount = newValue
65             UserDefaults.standard[.screenshotEditorColumnCount] = newValue
66         }
67     }
68     
69     var image: NSImage? {
70         
71         return tiledImageView.image
72     }
73     
74     @objc dynamic var currentTrimInfoIndex: Int {
75         
76         get { return realiesCurrentTrimInforIndex }
77         set {
78             guard 0..<trimInfo.count ~= newValue else { return }
79             
80             realiesCurrentTrimInforIndex = newValue
81             currentTrimInfo = trimInfo[newValue]
82         }
83     }
84     
85     private var editedImage: NSImage?
86     private var currentSelection: [ScreenshotInformation] = []
87     private var editedImages: [EditedImage] = []
88     private var realiesCurrentTrimInforIndex = UserDefaults.standard[.scrennshotEditorType]
89     private var currentTrimInfo: TrimRectInformation {
90         
91         didSet {
92             makeEditedImage()
93             trimInfo
94                 .index {
95                     
96                     if $0.name != currentTrimInfo.name { return false }
97                     return $0.rect == currentTrimInfo.rect
98                 }
99                 .map { UserDefaults.standard[.scrennshotEditorType] = $0 }
100         }
101     }
102     
103     private var selectionObservation: NSKeyValueObservation?
104     
105     var completeHandler: ((NSImage?) -> Void)?
106     
107     override func viewDidLoad() {
108         
109         super.viewDidLoad()
110         
111         selectionObservation = arrayController.observe(\NSArrayController.selectionIndexes) { [weak self] (_, _) in
112             
113             self?.updateSelections()
114         }
115         
116         currentTrimInfoIndex = UserDefaults.standard[.scrennshotEditorType]
117         updateSelections()
118     }
119     
120     override func viewWillAppear() {
121         
122         doneButton.action = #selector(ScreenshotEditorViewController.done(_:))
123     }
124     
125     private func updateSelections() {
126         
127         guard let selection = arrayController.selectedObjects as? [ScreenshotInformation] else { return }
128         
129         if selection == currentSelection { return }
130         
131         let removed: [ScreenshotInformation] = currentSelection.flatMap {
132             
133             selection.contains($0) ? nil : $0
134         }
135         
136         let appended: [ScreenshotInformation] = selection.flatMap {
137             
138             currentSelection.contains($0) ? nil : $0
139         }
140         
141         removed.forEach {
142             
143             removeEditedImage(url: $0.url)
144         }
145         
146         appended.forEach {
147             
148             appendEditedImage(url: $0.url)
149         }
150         
151         currentSelection = selection
152         makeEditedImage()
153     }
154     
155     private func removeEditedImage(url: URL) {
156         
157         _ = editedImages
158             .index { $0.url == url }
159             .map { editedImages.remove(at: $0) }
160     }
161     
162     private func appendEditedImage(url: URL) {
163         
164         NSImage(contentsOf: url)
165             .flatMap { EditedImage(image: $0, url: url) }
166             .map { editedImages.append($0) }
167     }
168     
169     private func makeEditedImage() {
170         
171         guard !editedImages.isEmpty else {
172             
173             tiledImageView.images = []
174             return
175         }
176         
177         DispatchQueue(label: "makeTrimedImage queue").async {
178             
179             let images: [NSImage] = self.editedImages.flatMap {
180                 
181                 guard let originalImage = NSImage(contentsOf: $0.url) else { return nil }
182                 
183                 let trimedImage = NSImage(size: self.currentTrimInfo.rect.size)
184                 
185                 trimedImage.lockFocus()
186                 originalImage.draw(at: .zero,
187                                    from: self.currentTrimInfo.rect,
188                                    operation: .copy,
189                                    fraction: 1.0)
190                 trimedImage.unlockFocus()
191                 
192                 return trimedImage
193             }
194             
195             DispatchQueue.main.async {
196                 
197                 self.tiledImageView.images = images
198             }
199         }
200     }
201     
202     @IBAction func done(_ sender: AnyObject?) {
203         
204         completeHandler?(self.image)
205     }
206 }
207
208 extension ScreenshotEditorViewController: NibLoadable {}