2 // CollectionView.swift
5 // Created by Hori,Masaki on 2017/01/02.
6 // Copyright © 2017年 Hori,Masaki. All rights reserved.
12 protocol Previewable {
14 var imageFrame: NSRect { get }
15 var view: NSView { get }
18 final class CollectionView: NSCollectionView {
20 private var selectionObservation: NSKeyValueObservation?
22 required init?(coder: NSCoder) {
24 super.init(coder: coder)
26 selectionObservation = observe(\CollectionView.selectionIndexPaths) { (_, _) in
28 if !QLPreviewPanel.sharedPreviewPanelExists() { return }
29 if !QLPreviewPanel.shared().isVisible { return }
31 DispatchQueue.main.asyncAfter(deadline: .now()) {
33 QLPreviewPanel.shared().reloadData()
40 extension CollectionView {
42 override func rightMouseDown(with event: NSEvent) {
44 guard let menu = menu else { return }
46 let mouse = convert(event.locationInWindow, from: nil)
48 guard let indexPath = indexPathForItem(at: mouse) else { return }
49 guard let _ = item(at: indexPath) else { return }
51 if !selectionIndexPaths.contains(indexPath) {
54 selectionIndexPaths = [indexPath]
57 NSMenu.popUpContextMenu(menu, with: event, for: self)
60 override func keyDown(with event: NSEvent) {
62 let key = event.charactersIgnoringModifiers
64 if key == " " { return quickLook(with: event) }
67 let leftArrow: UInt16 = 123
68 let rightArrow: UInt16 = 124
69 if event.keyCode == leftArrow || event.keyCode == rightArrow {
71 guard selectionIndexPaths.count != 0 else { return }
73 var index = selectionIndexPaths.first!.item
74 if event.keyCode == leftArrow && index != 0 { index -= 1 }
75 if event.keyCode == rightArrow && index != content.count - 1 { index += 1 }
76 let set: Set<IndexPath> = [IndexPath(item: index, section: 0)]
77 scrollToItems(at: set, scrollPosition: .nearestHorizontalEdge)
78 selectionIndexPaths = set
83 super.keyDown(with: event)
86 override func quickLook(with event: NSEvent) {
88 quickLookPreviewItems(nil)
91 override func quickLookPreviewItems(_ sender: Any?) {
93 if QLPreviewPanel.sharedPreviewPanelExists(),
94 QLPreviewPanel.shared().isVisible {
96 QLPreviewPanel.shared().orderOut(nil)
100 QLPreviewPanel.shared().makeKeyAndOrderFront(nil)
105 extension CollectionView: QLPreviewPanelDataSource, QLPreviewPanelDelegate {
107 override func acceptsPreviewPanelControl(_ panel: QLPreviewPanel!) -> Bool {
112 override func beginPreviewPanelControl(_ panel: QLPreviewPanel!) {
114 panel.dataSource = self
115 panel.delegate = self
118 override func endPreviewPanelControl(_ panel: QLPreviewPanel!) {
120 panel.dataSource = nil
124 func numberOfPreviewItems(in panel: QLPreviewPanel!) -> Int {
126 return selectionIndexPaths.count
129 func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -> QLPreviewItem! {
131 let selections = selectionIndexPaths.flatMap(item(at:))
133 guard case 0..<selections.count = index else { return nil }
134 guard let item = selections[index] as? QLPreviewItem else { return nil}
139 func previewPanel(_ panel: QLPreviewPanel!, handle event: NSEvent!) -> Bool {
141 if event.type == .keyDown {
151 func previewPanel(_ panel: QLPreviewPanel!, sourceFrameOnScreenFor item: QLPreviewItem!) -> NSRect {
153 guard let item = item as? Previewable else { return .zero }
155 let frame = convert(item.imageFrame, from: item.view)
156 let byWindow = convert(frame, to: nil)
158 return window?.convertToScreen(byWindow) ?? .zero