OSDN Git Service

定数の初期化方法を変更
[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 = [
38         TrimRectInformation(name: "Status", rect: NSRect(x: 328, y: 13, width: 470, height: 365)),
39         TrimRectInformation(name: "List", rect: NSRect(x: 362, y: 15, width: 438, height: 368)),
40         TrimRectInformation(name: "AirplaneBase", rect: NSRect(x: 575, y: 13, width: 225, height: 358))
41     ]
42     
43     override init(nibName: NSNib.Name?, bundle: Bundle?) {
44         
45         currentTrimInfo = trimInfo[0]
46         
47         super.init(nibName: ScreenshotEditorViewController.nibName, bundle: nil)
48     }
49     
50     required init?(coder: NSCoder) {
51         
52         fatalError("init(coder:) has not been implemented")
53     }
54     
55     
56     @IBOutlet weak var tiledImageView: TiledImageView!
57     @IBOutlet weak var doneButton: NSButton!
58     
59     @objc var columnCount: Int {
60         
61         get { return tiledImageView.columnCount }
62         set {
63             tiledImageView.columnCount = newValue
64             UserDefaults.standard[.screenshotEditorColumnCount] = newValue
65         }
66     }
67     
68     var image: NSImage? {
69         
70         return tiledImageView.image
71     }
72     
73     @objc dynamic var currentTrimInfoIndex: Int {
74         
75         get { return realiesCurrentTrimInforIndex }
76         set {
77             guard case 0..<trimInfo.count = newValue else { return }
78             
79             realiesCurrentTrimInforIndex = newValue
80             currentTrimInfo = trimInfo[newValue]
81         }
82     }
83     
84     private var editedImage: NSImage?
85     private var currentSelection: [ScreenshotInformation] = []
86     private var editedImages: [EditedImage] = []
87     private var realiesCurrentTrimInforIndex = UserDefaults.standard[.scrennshotEditorType]
88     private var currentTrimInfo: TrimRectInformation {
89         
90         didSet {
91             makeEditedImage()
92             trimInfo
93                 .index {
94                     
95                     if $0.name != currentTrimInfo.name { return false }
96                     return $0.rect == currentTrimInfo.rect
97                 }
98                 .map { UserDefaults.standard[.scrennshotEditorType] = $0 }
99         }
100     }
101     
102     private var selectionObservation: NSKeyValueObservation?
103     
104     var completeHandler: ((NSImage?) -> Void)?
105     
106     override func viewDidLoad() {
107         
108         super.viewDidLoad()
109         
110         selectionObservation = arrayController.observe(\NSArrayController.selectionIndexes) { [weak self] (_, _) in
111             
112             self?.updateSelections()
113         }
114         
115         currentTrimInfoIndex = UserDefaults.standard[.scrennshotEditorType]
116         updateSelections()
117     }
118     
119     override func viewWillAppear() {
120         
121         doneButton.action = #selector(ScreenshotEditorViewController.done(_:))
122     }
123     
124     private func updateSelections() {
125         
126         guard let selection = arrayController.selectedObjects as? [ScreenshotInformation] else { return }
127         
128         if selection == currentSelection { return }
129         
130         let removed: [ScreenshotInformation] = currentSelection.flatMap {
131             
132             selection.contains($0) ? nil : $0
133         }
134         
135         let appended: [ScreenshotInformation] = selection.flatMap {
136             
137             currentSelection.contains($0) ? nil : $0
138         }
139         
140         removed.forEach {
141             
142             removeEditedImage(url: $0.url)
143         }
144         
145         appended.forEach {
146             
147             appendEditedImage(url: $0.url)
148         }
149         
150         currentSelection = selection
151         makeEditedImage()
152     }
153     
154     private func removeEditedImage(url: URL) {
155         
156         _ = editedImages
157             .index { $0.url == url }
158             .map { editedImages.remove(at: $0) }
159     }
160     
161     private func appendEditedImage(url: URL) {
162         
163         NSImage(contentsOf: url)
164             .flatMap { EditedImage(image: $0, url: url) }
165             .map { editedImages.append($0) }
166     }
167     
168     private func makeEditedImage() {
169         
170         guard !editedImages.isEmpty else {
171             
172             tiledImageView.images = []
173             return
174         }
175         
176         DispatchQueue(label: "makeTrimedImage queue").async {
177             
178             let images: [NSImage] = self.editedImages.flatMap {
179                 
180                 guard let originalImage = NSImage(contentsOf: $0.url) else { return nil }
181                 
182                 let trimedImage = NSImage(size: self.currentTrimInfo.rect.size)
183                 
184                 trimedImage.lockFocus()
185                 originalImage.draw(at: .zero,
186                                    from: self.currentTrimInfo.rect,
187                                    operation: .copy,
188                                    fraction: 1.0)
189                 trimedImage.unlockFocus()
190                 
191                 return trimedImage
192             }
193             
194             DispatchQueue.main.async {
195                 
196                 self.tiledImageView.images = images
197             }
198         }
199     }
200     
201     @IBAction func done(_ sender: AnyObject?) {
202         
203         completeHandler?(self.image)
204     }
205 }
206
207 extension ScreenshotEditorViewController: NibLoadable {}