OSDN Git Service

ColorSetを変更
[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 URLImage {
12     
13     var image: NSImage
14     var url: URL
15     
16     init(image: NSImage, url: URL) {
17         
18         self.image = image
19         self.url = url
20     }
21 }
22
23 /// 切り取りサイズ、位置と名前
24 final class TrimRectInformation: NSObject {
25     
26     @objc private(set) var name: String
27     private(set) var rect: NSRect
28     
29     fileprivate init(name: String, rect: NSRect) {
30         
31         self.name = name
32         self.rect = rect
33     }
34 }
35
36 final class ScreenshotEditorViewController: BridgeViewController {
37     
38     @objc let trimInfo = [
39         TrimRectInformation(name: "Status", rect: NSRect(x: 328, y: 13, width: 470, height: 365)),
40         TrimRectInformation(name: "List", rect: NSRect(x: 362, y: 15, width: 438, height: 368)),
41         TrimRectInformation(name: "AirplaneBase", rect: NSRect(x: 575, y: 13, width: 225, height: 358))
42     ]
43     
44     override init(nibName: NSNib.Name?, bundle: Bundle?) {
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 private weak var tiledImageView: TiledImageView!
58     @IBOutlet private weak var doneButton: NSButton!
59     
60     @objc var columnCount: Int {
61         
62         get { return tiledImageView.columnCount }
63         set {
64             
65             tiledImageView.columnCount = newValue
66             UserDefaults.standard[.screenshotEditorColumnCount] = newValue
67         }
68     }
69     
70     var image: NSImage? {
71         
72         return tiledImageView.image
73     }
74     
75     @objc dynamic var currentTrimInfoIndex: Int {
76         
77         get { return realiesCurrentTrimInforIndex }
78         set {
79             
80             guard case 0..<trimInfo.count = newValue else {
81                 
82                 return
83             }
84             
85             realiesCurrentTrimInforIndex = newValue
86             currentTrimInfo = trimInfo[newValue]
87         }
88     }
89     
90     private var editedImage: NSImage?
91     private var currentSelection: [ScreenshotInformation] = []
92     private var originalImages: [URLImage] = []
93     private var realiesCurrentTrimInforIndex = UserDefaults.standard[.scrennshotEditorType]
94     private var currentTrimInfo: TrimRectInformation {
95         
96         didSet {
97             
98             makeTrimedImage()
99             trimInfo
100                 .index {
101                     
102                     if $0.name != currentTrimInfo.name {
103                         
104                         return false
105                     }
106                     
107                     return $0.rect == currentTrimInfo.rect
108                 }
109                 .map { UserDefaults.standard[.scrennshotEditorType] = $0 }
110         }
111     }
112     
113     private var selectionObservation: NSKeyValueObservation?
114     
115     var completeHandler: ((NSImage?) -> Void)?
116     
117     override func viewDidLoad() {
118         
119         super.viewDidLoad()
120         
121         selectionObservation = arrayController.observe(\NSArrayController.selectionIndexes) { [weak self] (_, _) in
122             
123             self?.updateSelections()
124         }
125         
126         currentTrimInfoIndex = UserDefaults.standard[.scrennshotEditorType]
127         updateSelections()
128     }
129     
130     override func viewWillAppear() {
131         
132         doneButton.action = #selector(ScreenshotEditorViewController.done(_:))
133     }
134     
135     private func updateSelections() {
136         
137         guard let selection = arrayController.selectedObjects as? [ScreenshotInformation] else {
138             
139             return
140         }
141         
142         if selection == currentSelection {
143             
144             return
145         }
146         
147         let removed: [ScreenshotInformation] = currentSelection.compactMap {
148             
149             selection.contains($0) ? nil : $0
150         }
151         
152         let appended: [ScreenshotInformation] = selection.compactMap {
153             
154             currentSelection.contains($0) ? nil : $0
155         }
156         
157         removed.forEach {
158             
159             removeOriginalImage(url: $0.url)
160         }
161         
162         appended.forEach {
163             
164             appendOriginalImage(url: $0.url)
165         }
166         
167         currentSelection = selection
168         makeTrimedImage()
169     }
170     
171     private func removeOriginalImage(url: URL) {
172         
173         _ = originalImages
174             .index { $0.url == url }
175             .map { originalImages.remove(at: $0) }
176     }
177     
178     private func appendOriginalImage(url: URL) {
179         
180         NSImage(contentsOf: url)
181             .flatMap { URLImage(image: $0, url: url) }
182             .map { originalImages.append($0) }
183     }
184     
185     private func makeTrimedImage() {
186         
187         guard !originalImages.isEmpty else {
188             
189             tiledImageView.images = []
190             
191             return
192         }
193         
194         DispatchQueue(label: "makeTrimedImage queue").async {
195             
196             let images: [NSImage] = self.originalImages.compactMap {
197                 
198                 let trimedImage = NSImage(size: self.currentTrimInfo.rect.size)
199                 
200                 trimedImage.lockFocus()
201                 $0.image.draw(at: .zero,
202                                    from: self.currentTrimInfo.rect,
203                                    operation: .copy,
204                                    fraction: 1.0)
205                 trimedImage.unlockFocus()
206                 
207                 return trimedImage
208             }
209             
210             DispatchQueue.main.async {
211                 
212                 self.tiledImageView.images = images
213             }
214         }
215     }
216     
217     @IBAction func done(_ sender: AnyObject?) {
218         
219         completeHandler?(self.image)
220     }
221 }
222
223 extension ScreenshotEditorViewController: NibLoadable {}