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) {
}
}
-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) {
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
}
}
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]
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 {}