OSDN Git Service

Doutaku を 1.0 にアップデート
[kcd/KCD.git] / KCD / CollectionView.swift
1 //
2 //  CollectionView.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/02.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10 import Quartz
11
12 protocol Previewable {
13     
14     var imageFrame: NSRect { get }
15     var view: NSView { get }
16 }
17
18 final class CollectionView: NSCollectionView {
19     
20     private var selectionObservation: NSKeyValueObservation?
21     
22     required init?(coder: NSCoder) {
23         
24         super.init(coder: coder)
25         
26         selectionObservation = observe(\CollectionView.selectionIndexPaths) { (_, _) in
27             
28             if !QLPreviewPanel.sharedPreviewPanelExists() {
29                 
30                 return
31             }
32             if !QLPreviewPanel.shared().isVisible {
33                 
34                 return
35             }
36             
37             DispatchQueue.main.asyncAfter(deadline: .now()) {
38                 
39                 QLPreviewPanel.shared().reloadData()
40             }
41         }
42     }
43     
44 }
45
46 extension CollectionView {
47     
48     override func rightMouseDown(with event: NSEvent) {
49         
50         guard let menu = menu else {
51             
52             return
53         }
54         
55         let mouse = convert(event.locationInWindow, from: nil)
56         
57         guard let indexPath = indexPathForItem(at: mouse) else {
58             
59             return
60         }
61         guard let _ = item(at: indexPath) else {
62             
63             return
64         }
65         
66         if !selectionIndexPaths.contains(indexPath) {
67             
68             deselectAll(nil)
69             selectionIndexPaths = [indexPath]
70         }
71         
72         NSMenu.popUpContextMenu(menu, with: event, for: self)
73     }
74     
75     override func keyDown(with event: NSEvent) {
76         
77         let key = event.charactersIgnoringModifiers
78         
79         if key == " " {
80             
81             return quickLook(with: event)
82         }
83         
84         //  左右矢印キーの時の動作
85         let leftArrow: UInt16 = 123
86         let rightArrow: UInt16 = 124
87         if event.keyCode == leftArrow || event.keyCode == rightArrow {
88             
89             guard selectionIndexPaths.count != 0 else {
90                 
91                 return
92             }
93             
94             var index = selectionIndexPaths.first!.item
95             if event.keyCode == leftArrow && index != 0 {
96                 
97                 index -= 1
98             }
99             if event.keyCode == rightArrow && index != content.count - 1 {
100                 
101                 index += 1
102             }
103             let set: Set<IndexPath> = [IndexPath(item: index, section: 0)]
104             scrollToItems(at: set, scrollPosition: .nearestHorizontalEdge)
105             selectionIndexPaths = set
106             
107             return
108         }
109         
110         super.keyDown(with: event)
111     }
112     
113     override func quickLook(with event: NSEvent) {
114         
115         quickLookPreviewItems(nil)
116     }
117     
118     override func quickLookPreviewItems(_ sender: Any?) {
119         
120         if QLPreviewPanel.sharedPreviewPanelExists(),
121             QLPreviewPanel.shared().isVisible {
122             
123             QLPreviewPanel.shared().orderOut(nil)
124             
125         } else {
126             
127             QLPreviewPanel.shared().makeKeyAndOrderFront(nil)
128         }
129     }
130 }
131
132 extension CollectionView: QLPreviewPanelDataSource, QLPreviewPanelDelegate {
133     
134     override func acceptsPreviewPanelControl(_ panel: QLPreviewPanel!) -> Bool {
135         
136         return true
137     }
138     
139     override func beginPreviewPanelControl(_ panel: QLPreviewPanel!) {
140         
141         panel.dataSource = self
142         panel.delegate = self
143     }
144     
145     override func endPreviewPanelControl(_ panel: QLPreviewPanel!) {
146         
147         panel.dataSource = nil
148         panel.delegate = nil
149     }
150     
151     func numberOfPreviewItems(in panel: QLPreviewPanel!) -> Int {
152         
153         return selectionIndexPaths.count
154     }
155     
156     func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -> QLPreviewItem! {
157         
158         let selections = selectionIndexPaths.compactMap(item(at:))
159         
160         guard case 0..<selections.count = index else {
161             
162             return nil
163         }
164         guard let item = selections[index] as? QLPreviewItem else {
165             
166             return nil
167         }
168         
169         return item
170     }
171     
172     func previewPanel(_ panel: QLPreviewPanel!, handle event: NSEvent!) -> Bool {
173         
174         if event.type == .keyDown {
175             
176             keyDown(with: event)
177             
178             return true
179         }
180         
181         return false
182     }
183     
184     func previewPanel(_ panel: QLPreviewPanel!, sourceFrameOnScreenFor item: QLPreviewItem!) -> NSRect {
185         
186         guard let item = item as? Previewable else {
187             
188             return .zero
189         }
190         
191         let frame = convert(item.imageFrame, from: item.view)
192         let byWindow = convert(frame, to: nil)
193         
194         return window?.convertToScreen(byWindow) ?? .zero
195     }
196 }