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() {
32 if !QLPreviewPanel.shared().isVisible {
37 DispatchQueue.main.asyncAfter(deadline: .now()) {
39 QLPreviewPanel.shared().reloadData()
46 extension CollectionView {
48 override func rightMouseDown(with event: NSEvent) {
50 guard let menu = menu else {
55 let mouse = convert(event.locationInWindow, from: nil)
57 guard let indexPath = indexPathForItem(at: mouse) else {
61 guard let _ = item(at: indexPath) else {
66 if !selectionIndexPaths.contains(indexPath) {
69 selectionIndexPaths = [indexPath]
72 NSMenu.popUpContextMenu(menu, with: event, for: self)
75 override func keyDown(with event: NSEvent) {
77 let key = event.charactersIgnoringModifiers
81 return quickLook(with: event)
85 let leftArrow: UInt16 = 123
86 let rightArrow: UInt16 = 124
87 if event.keyCode == leftArrow || event.keyCode == rightArrow {
89 guard selectionIndexPaths.count != 0 else {
94 var index = selectionIndexPaths.first!.item
95 if event.keyCode == leftArrow && index != 0 {
99 if event.keyCode == rightArrow && index != content.count - 1 {
103 let set: Set<IndexPath> = [IndexPath(item: index, section: 0)]
104 scrollToItems(at: set, scrollPosition: .nearestHorizontalEdge)
105 selectionIndexPaths = set
110 super.keyDown(with: event)
113 override func quickLook(with event: NSEvent) {
115 quickLookPreviewItems(nil)
118 override func quickLookPreviewItems(_ sender: Any?) {
120 if QLPreviewPanel.sharedPreviewPanelExists(),
121 QLPreviewPanel.shared().isVisible {
123 QLPreviewPanel.shared().orderOut(nil)
127 QLPreviewPanel.shared().makeKeyAndOrderFront(nil)
132 extension CollectionView: QLPreviewPanelDataSource, QLPreviewPanelDelegate {
134 override func acceptsPreviewPanelControl(_ panel: QLPreviewPanel!) -> Bool {
139 override func beginPreviewPanelControl(_ panel: QLPreviewPanel!) {
141 panel.dataSource = self
142 panel.delegate = self
145 override func endPreviewPanelControl(_ panel: QLPreviewPanel!) {
147 panel.dataSource = nil
151 func numberOfPreviewItems(in panel: QLPreviewPanel!) -> Int {
153 return selectionIndexPaths.count
156 func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -> QLPreviewItem! {
158 let selections = selectionIndexPaths.compactMap(item(at:))
160 guard case 0..<selections.count = index else {
164 guard let item = selections[index] as? QLPreviewItem else {
172 func previewPanel(_ panel: QLPreviewPanel!, handle event: NSEvent!) -> Bool {
174 if event.type == .keyDown {
184 func previewPanel(_ panel: QLPreviewPanel!, sourceFrameOnScreenFor item: QLPreviewItem!) -> NSRect {
186 guard let item = item as? Previewable else {
191 let frame = convert(item.imageFrame, from: item.view)
192 let byWindow = convert(frame, to: nil)
194 return window?.convertToScreen(byWindow) ?? .zero