OSDN Git Service

Equatableを自動実装させるようにした
[kcd/KCD.git] / KCD / ScreenshotEditorViewController.swift
index cb068dd..52600c9 100644 (file)
@@ -8,22 +8,23 @@
 
 import Cocoa
 
-fileprivate struct EditedImage {
+private struct URLImage {
     
-    var editedImage: NSImage
+    var image: NSImage
     var url: URL
     
     init(image: NSImage, url: URL) {
         
-        editedImage = image
+        self.image = image
         self.url = url
     }
 }
 
+/// 切り取りサイズ、位置と名前
 final class TrimRectInformation: NSObject {
     
-    fileprivate(set) var name: String
-    fileprivate(set) var rect: NSRect
+    @objc private(set) var name: String
+    private(set) var rect: NSRect
     
     fileprivate init(name: String, rect: NSRect) {
         
@@ -32,27 +33,19 @@ final class TrimRectInformation: NSObject {
     }
 }
 
-fileprivate extension Selector {
-    
-    static let done = #selector(ScreenshotEditorViewController.done(_:))
-    static let changeToDetail = #selector(ScreenshotListWindowController.changeToDetail(_:))
-    static let registerImage = #selector(ScreenshotListViewController.registerImage(_:))
-}
-
 final class ScreenshotEditorViewController: BridgeViewController {
     
-    let trimInfo: [TrimRectInformation]
+    @objc let trimInfo = [
+        TrimRectInformation(name: "Status", rect: NSRect(x: 328, y: 13, width: 470, height: 365)),
+        TrimRectInformation(name: "List", rect: NSRect(x: 362, y: 15, width: 438, height: 368)),
+        TrimRectInformation(name: "AirplaneBase", rect: NSRect(x: 575, y: 13, width: 225, height: 358))
+    ]
     
-    override init?(nibName: String?, bundle: Bundle?) {
+    override init(nibName: NSNib.Name?, bundle: Bundle?) {
         
-        trimInfo = [
-            TrimRectInformation(name: "Status", rect: NSRect(x: 328, y: 13, width: 470, height: 365)),
-            TrimRectInformation(name: "List", rect: NSRect(x: 362, y: 15, width: 438, height: 368)),
-            TrimRectInformation(name: "AirplaneBase", rect: NSRect(x: 575, y: 13, width: 225, height: 358))
-        ]
         currentTrimInfo = trimInfo[0]
         
-        super.init(nibName: "ScreenshotEditorViewController", bundle: nil)
+        super.init(nibName: ScreenshotEditorViewController.nibName, bundle: nil)
     }
     
     required init?(coder: NSCoder) {
@@ -60,20 +53,17 @@ final class ScreenshotEditorViewController: BridgeViewController {
         fatalError("init(coder:) has not been implemented")
     }
     
-    deinit {
-        
-        arrayController.removeObserver(self, forKeyPath: NSSelectionIndexesBinding)
-    }
     
-    @IBOutlet weak var tiledImageView: TiledImageView!
-    @IBOutlet weak var doneButton: NSButton!
+    @IBOutlet private weak var tiledImageView: TiledImageView!
+    @IBOutlet private weak var doneButton: NSButton!
     
-    var columnCount: Int {
+    @objc var columnCount: Int {
         
         get { return tiledImageView.columnCount }
         set {
+            
             tiledImageView.columnCount = newValue
-            UserDefaults.standard.screenshotEditorColumnCount = newValue
+            UserDefaults.standard[.screenshotEditorColumnCount] = newValue
         }
     }
     
@@ -82,12 +72,15 @@ final class ScreenshotEditorViewController: BridgeViewController {
         return tiledImageView.image
     }
     
-    dynamic var currentTrimInfoIndex: Int {
+    @objc dynamic var currentTrimInfoIndex: Int {
         
         get { return realiesCurrentTrimInforIndex }
         set {
-            guard 0..<trimInfo.count ~= newValue
-                else { return }
+            
+            guard case 0..<trimInfo.count = newValue else {
+                
+                return
+            }
             
             realiesCurrentTrimInforIndex = newValue
             currentTrimInfo = trimInfo[newValue]
@@ -96,133 +89,135 @@ final class ScreenshotEditorViewController: BridgeViewController {
     
     private var editedImage: NSImage?
     private var currentSelection: [ScreenshotInformation] = []
-    private var editedImages: [EditedImage] = []
-    private var realiesCurrentTrimInforIndex = UserDefaults.standard.scrennshotEditorType
+    private var originalImages: [URLImage] = []
+    private var realiesCurrentTrimInforIndex = UserDefaults.standard[.scrennshotEditorType]
     private var currentTrimInfo: TrimRectInformation {
         
         didSet {
-            makeEditedImage()
+            
+            makeTrimedImage()
             trimInfo
                 .index {
                     
-                    if $0.name != currentTrimInfo.name { return false }
+                    if $0.name != currentTrimInfo.name {
+                        
+                        return false
+                    }
+                    
                     return $0.rect == currentTrimInfo.rect
                 }
-                .map { UserDefaults.standard.scrennshotEditorType = $0 }
+                .map { UserDefaults.standard[.scrennshotEditorType] = $0 }
         }
     }
     
+    private var selectionObservation: NSKeyValueObservation?
+    
+    var completeHandler: ((NSImage?) -> Void)?
+    
     override func viewDidLoad() {
         
         super.viewDidLoad()
         
-        arrayController.addObserver(self, forKeyPath: NSSelectionIndexesBinding, context: nil)
-        currentTrimInfoIndex = UserDefaults.standard.scrennshotEditorType
+        selectionObservation = arrayController.observe(\NSArrayController.selectionIndexes) { [weak self] (_, _) in
+            
+            self?.updateSelections()
+        }
+        
+        currentTrimInfoIndex = UserDefaults.standard[.scrennshotEditorType]
         updateSelections()
     }
     
     override func viewWillAppear() {
         
-        doneButton.action = .done
+        doneButton.action = #selector(ScreenshotEditorViewController.done(_:))
     }
     
-    override func observeValue(forKeyPath keyPath: String?,
-                               of object: Any?,
-                               change: [NSKeyValueChangeKey : Any]?,
-                               context: UnsafeMutableRawPointer?) {
+    private func updateSelections() {
         
-        if keyPath == NSSelectionIndexesBinding {
-            
-            updateSelections()
+        guard let selection = arrayController.selectedObjects as? [ScreenshotInformation] else {
             
             return
         }
         
-        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
-    }
-    
-    private func updateSelections() {
-        
-        guard let selection = arrayController.selectedObjects as? [ScreenshotInformation]
-            else { return }
-        
-        if selection == currentSelection { return }
+        if selection == currentSelection {
+            
+            return
+        }
         
-        let removed: [ScreenshotInformation] = currentSelection.flatMap {
+        let removed: [ScreenshotInformation] = currentSelection.compactMap {
             
             selection.contains($0) ? nil : $0
         }
         
-        let appended: [ScreenshotInformation] = selection.flatMap {
+        let appended: [ScreenshotInformation] = selection.compactMap {
             
             currentSelection.contains($0) ? nil : $0
         }
         
         removed.forEach {
             
-            removeEditedImage(url: $0.url)
+            removeOriginalImage(url: $0.url)
         }
         
         appended.forEach {
             
-            appendEditedImage(url: $0.url)
+            appendOriginalImage(url: $0.url)
         }
         
         currentSelection = selection
-        makeEditedImage()
+        makeTrimedImage()
     }
     
-    private func removeEditedImage(url: URL) {
+    private func removeOriginalImage(url: URL) {
         
-        let _ = editedImages
+        _ = originalImages
             .index { $0.url == url }
-            .map { editedImages.remove(at: $0) }
+            .map { originalImages.remove(at: $0) }
     }
     
-    private func appendEditedImage(url: URL) {
+    private func appendOriginalImage(url: URL) {
         
         NSImage(contentsOf: url)
-            .flatMap { EditedImage(image: $0, url: url) }
-            .map { editedImages.append($0) }
+            .flatMap { URLImage(image: $0, url: url) }
+            .map { originalImages.append($0) }
     }
     
-    private func makeEditedImage() {
+    private func makeTrimedImage() {
         
-        guard !editedImages.isEmpty else {
+        guard !originalImages.isEmpty else {
+            
             tiledImageView.images = []
+            
             return
         }
         
-        DispatchQueue(label: "makeTrimedImage queue")
-            .async {
+        DispatchQueue(label: "makeTrimedImage queue").async {
+            
+            let images: [NSImage] = self.originalImages.compactMap {
                 
-                let images: [NSImage] = self.editedImages.flatMap {
-                    
-                    guard let originalImage = NSImage(contentsOf: $0.url) else { return nil }
-                    
-                    let trimedImage = NSImage(size: self.currentTrimInfo.rect.size)
-                    
-                    trimedImage.lockFocus()
-                    originalImage.draw(at: .zero,
-                                       from: self.currentTrimInfo.rect,
-                                       operation: NSCompositeCopy,
-                                       fraction: 1.0)
-                    trimedImage.unlockFocus()
-                    
-                    return trimedImage
-                }
+                let trimedImage = NSImage(size: self.currentTrimInfo.rect.size)
                 
-                DispatchQueue.main.async {
-                    
-                    self.tiledImageView.images = images
-                }
+                trimedImage.lockFocus()
+                $0.image.draw(at: .zero,
+                                   from: self.currentTrimInfo.rect,
+                                   operation: .copy,
+                                   fraction: 1.0)
+                trimedImage.unlockFocus()
+                
+                return trimedImage
+            }
+            
+            DispatchQueue.main.async {
+                
+                self.tiledImageView.images = images
+            }
         }
     }
     
-    // TODO: 外部から End Handlerを登録できるようにして依存をなくす
     @IBAction func done(_ sender: AnyObject?) {
         
-        NSApplication.shared().sendAction(.registerImage, to: nil, from: self.image)
-        NSApplication.shared().sendAction(.changeToDetail, to: nil, from: sender)
+        completeHandler?(self.image)
     }
 }
+
+extension ScreenshotEditorViewController: NibLoadable {}