123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681 |
- //
- // KMThumbnailView.swift
- // PDF Reader Pro
- //
- // Created by tangchao on 2023/5/4.
- //
- import Cocoa
- @objc enum KMThumbnailViewDragInfoKey: Int {
- case dropOperation = 0
- case draggingInfo = 1
- }
- @objc protocol KMThumbnailViewDelegate : NSObjectProtocol {
- // layout
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, minimumLineSpacingForSectionAt section: Int) -> CGFloat
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, insetForSectionAt section: Int) -> NSEdgeInsets
-
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, sizeForItemAt indexpath: IndexPath) -> NSSize
-
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, numberOfItemsInSection section: Int) -> Int
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, itemForRepresentedObjectAt indexpath: IndexPath) -> NSCollectionViewItem
-
- // Drag & Drop
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItemsAt indexes: IndexSet)
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, dragOperation operation: NSDragOperation)
-
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, canPasteboardWriterForItemAt indexPath: IndexPath) -> Bool
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, shouldPasteboardWriterForItemAt indexPath: IndexPath) -> Bool
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, pasteboardWriterForItemAt indexPath: IndexPath) -> NSPasteboardWriting?
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, canDragItemsAt indexPaths: Set<IndexPath>, with event: NSEvent) -> Bool
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, shouldAcceptDrop draggingInfo: NSDraggingInfo, indexPath: IndexPath, dropOperation: NSCollectionView.DropOperation) -> Bool
- // 本地拖拽
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, didDrag dragedIndexPaths: [IndexPath], indexpath: IndexPath, dragInfo:[KMThumbnailViewDragInfoKey.RawValue:Any])
- // 外部拖拽
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, didDragAddFiles files: [URL], indexpath: IndexPath)
-
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, didSelectItemAt indexpath: IndexPath, object: AnyObject?)
- @objc optional func thumbnailView(thumbanView: KMThumbnailView, rightMouseDidClick indexpath: IndexPath, item: NSCollectionViewItem?, object: AnyObject?)
- }
- private let _KMThumbnailView_collectionViewDrop_lineViewClassName = "NSCollectionViewDropTargetGapIndicator"
- @objc class KMThumbnailView_CollectionView: NSCollectionView {
- // 是否点击空白取消选中 默认取消选中
- var mouseDownCancelSelected: Bool = true
-
- var hasDragLineView: Bool = true {
- didSet {
- if (!self.hasDragLineView) {
- // 隐藏视图
- for view in self.subviews {
- guard let lineClass = NSClassFromString(_KMThumbnailView_collectionViewDrop_lineViewClassName) else {
- continue
- }
- if (view.isKind(of: lineClass)) {
- // view.frame = NSZeroRect
- view.isHidden = true
- }
- }
- }
- }
- }
-
- override func addSubview(_ view: NSView) {
- if (self.hasDragLineView) {
- return super.addSubview(view)
- }
-
- if let lineClass = NSClassFromString(_KMThumbnailView_collectionViewDrop_lineViewClassName) {
- if (view.isKind(of: lineClass)) {
- Swift.debugPrint("Find Line View......")
- return
- } else {
- super.addSubview(view)
- }
- }
-
- super.addSubview(view)
- }
-
- override func mouseDown(with event: NSEvent) {
- let point = convert(event.locationInWindow, from: nil)
-
- if self.mouseDownCancelSelected {
- super.mouseDown(with: event)
- } else {
- if let indexPath = indexPathForItem(at: point) {
- // 用户点击了一个项,处理点击事件
- super.mouseDown(with: event)
- } else {
- // 用户点击了空白区域,不取消选中项
- }
- }
- }
- }
- @objc class KMThumbnailView: NSView {
-
- open weak var delegate: KMThumbnailViewDelegate?
-
- internal let localForDraggedTypes = kKMLocalForDraggedTypes
- internal var dragedIndexPaths: [IndexPath] = []
- var kmAllowedFileTypes: [String]?
- // 记录拖拽移动后的位置
- fileprivate var _dragMoveFlagIndexpath: IndexPath?
- fileprivate var _dragMoveFlagIndexs: IndexSet?
-
- // 是否隐藏拖放线 dragMoveEffectAnimated 属性为false才有效
- var hasDragLineView: Bool = true {
- didSet {
- if (!self.dragMoveEffectAnimated) {
- self.collectionView_.hasDragLineView = self.hasDragLineView
- } else {
- self.collectionView_.hasDragLineView = false
- }
- }
- }
- // 是否显示拖放移动动效 为true时 hasDragLineView属性设置是
- var dragMoveEffectAnimated: Bool = false {
- didSet {
- self.hasDragLineView = !self.dragMoveEffectAnimated
- }
- }
- override init(frame frameRect: NSRect) {
- super.init(frame: frameRect)
-
- self.initDefaultValue()
- self.initSubViews()
- }
-
- required public init?(coder: NSCoder) {
- super.init(coder: coder)
-
- self.initDefaultValue()
- self.initSubViews()
- }
-
- open var minimumLineSpacing: CGFloat = 0.0 {
- didSet {
- self.reloadData()
- }
- }
- open var minimumInteritemSpacing: CGFloat = 0.0 {
- didSet {
- self.reloadData()
- }
- }
- open var itemSize: NSSize = NSMakeSize(60, 80) {
- didSet {
- self.reloadData()
- }
- }
- open var sectionInset: NSEdgeInsets = NSEdgeInsetsZero {
- didSet {
- self.reloadData()
- }
- }
-
- open var numberOfSections: Int = 0 {
- didSet {
- self.reloadData()
- }
- }
-
- var selectionIndexPaths: Set<IndexPath> {
- get {
- return self.collectionView.selectionIndexPaths
- }
- set {
- var indexpaths: Set<IndexPath> = []
- for indexpath in newValue {
- if (indexpath.section >= self.collectionView.numberOfSections) {
- continue
- }
- if indexpath.section < 0 {
- continue
- }
- if (indexpath.item >= self.collectionView.numberOfItems(inSection: indexpath.section)) {
- continue
- }
- if indexpath.item < 0 {
- continue
- }
-
- indexpaths.insert(indexpath)
- }
-
- self.collectionView.selectionIndexPaths = indexpaths
- }
- }
-
- // MARK: - Publick Methods
-
- public func initDefaultValue() {
- self.collectionView.registerForDraggedTypes([self.localForDraggedTypes, .fileURL,.string,.pdf])
- }
-
- public func initSubViews() {
- self.addSubview(self.scrollView)
- self.scrollView.frame = self.bounds
- self.scrollView.autoresizingMask = [.width, .height]
-
- self.scrollView.documentView = self.collectionView
- }
-
- // MARK: - register ItemClass
-
- open func register(_ itemClass: AnyClass?) {
- guard let itemClass_ = itemClass else {
- return
- }
-
- self.register(itemClass_, forItemWithIdentifier: NSStringFromClass(itemClass_))
- }
-
- open func register(_ itemClass: AnyClass?, forItemWithIdentifier identifier: String) {
- self.collectionView.register(itemClass, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: identifier))
- }
-
- // MARK: - 刷新UI
-
- public func reloadData(indexs: Set<IndexPath> = []) {
- if (indexs.count == 0) {
- if (Thread.isMainThread) {
- self.collectionView.reloadData()
- } else {
- DispatchQueue.main.async {
- self.collectionView.reloadData()
- }
- }
- } else {
- var indexpaths: Set<IndexPath> = []
- for index in indexs {
- if (index.section >= self.collectionView.numberOfSections) {
- continue
- }
- if (index.item >= self.collectionView.numberOfItems(inSection: index.section)) {
- continue
- }
-
- indexpaths.insert(index)
- }
- if (indexpaths.count == 0) {
- return
- }
-
- if (Thread.isMainThread) {
- self.collectionView.reloadItems(at: indexpaths)
- } else {
- DispatchQueue.main.async {
- self.collectionView.reloadItems(at: indexpaths)
- }
- }
- }
- }
-
- // MARK: - 属性 【懒加载】
-
- internal lazy var scrollView_: NSScrollView = {
- let view = NSScrollView()
-
- view.hasHorizontalScroller = true
- view.hasVerticalScroller = true
- view.autohidesScrollers = true
- view.minMagnification = 1.0
- view.scrollerStyle = .overlay
-
- view.wantsLayer = true
- view.layer?.backgroundColor = NSColor.clear.cgColor
-
- view.wantsLayer = true
- view.contentView.layer?.backgroundColor = .white
-
- return view
- }()
- var scrollView: NSScrollView {
- get {
- return self.scrollView_
- }
- }
-
- internal lazy var collectionView_: KMThumbnailView_CollectionView = {
- let view = KMThumbnailView_CollectionView()
- view.autoresizingMask = [.width, .height]
-
- let layout = NSCollectionViewFlowLayout()
- layout.sectionInset = NSEdgeInsetsMake(8, 15, 8, 15)
- layout.minimumLineSpacing = 0
- layout.minimumInteritemSpacing = 0
- view.collectionViewLayout = layout
-
- view.delegate = self
- view.dataSource = self
-
- view.register(NSCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMPDFThumbnailItem"))
- view.isSelectable = true
-
- view.wantsLayer = true
- view.layer?.backgroundColor = NSColor.km_init(hex: "#F7F8FA").cgColor
-
- return view
- }()
- var collectionView: KMThumbnailView_CollectionView {
- get {
- return self.collectionView_
- }
- }
-
- // MARK: - Private Methods
-
- private func _moveItemForDrag(to toIndexPath: IndexPath) -> Bool {
- if (self.dragedIndexPaths.isEmpty) {
- Swift.debugPrint("not find selected items.\(self.dragedIndexPaths)")
- return false
- }
- if (self.dragedIndexPaths.contains(toIndexPath) == false) { // 目标位置不在拖放数组里
- if (self._dragMoveFlagIndexpath == nil) { // 第一次移动
- self.collectionView.animator().moveItem(at: self.dragedIndexPaths.first!, to: toIndexPath)
- Swift.debugPrint("moveBegin, \(self.dragedIndexPaths.first!.item)->\(toIndexPath.item)")
-
- // 标记位置
- self._dragMoveFlagIndexpath = toIndexPath
- return true
- } else { // 已有移动
- if (self._dragMoveFlagIndexpath! != toIndexPath) {
- self.collectionView.animator().moveItem(at: self._dragMoveFlagIndexpath!, to: toIndexPath)
- Swift.debugPrint("move..., \(self._dragMoveFlagIndexpath!.item)->\(toIndexPath.item)")
-
- // 标记位置
- self._dragMoveFlagIndexpath = toIndexPath
- return true
- } else {
- Swift.debugPrint("drag... ")
- }
- }
- } else if (self._dragMoveFlagIndexpath != nil) { // 目标位置在拖放数组里且已有移动
- if (self._dragMoveFlagIndexpath! != toIndexPath) {
- self.collectionView.animator().moveItem(at: self._dragMoveFlagIndexpath!, to: toIndexPath)
- Swift.debugPrint("move..., \(self._dragMoveFlagIndexpath!.item)->\(toIndexPath.item)")
-
- // 标记位置
- self._dragMoveFlagIndexpath = toIndexPath
- return true
- } else {
- Swift.debugPrint("drag... ")
- }
- }
-
- return false
- }
-
- private func _moveItemsForDrag(at itemIndexPaths: Set<IndexPath>, to toIndexPath: IndexPath) -> Bool {
- if (itemIndexPaths.isEmpty) {
- return false
- }
-
- var itemIndexs = IndexSet()
- for ip in itemIndexPaths {
- itemIndexs.insert(ip.item)
- }
- return self._moveItemsForDrag(at: itemIndexs, to: toIndexPath.item)
- }
-
- private func _moveItemsForDrag(at itemIndexs: IndexSet, to toIndex: Int) -> Bool {
- if (itemIndexs.isEmpty) {
- return false
- }
-
- var flagIndexs = IndexSet()
- if (itemIndexs.first! > toIndex) { // 往前拖放
- // 3,4 -> 2
- // 3->2,4->3
- var cnt: Int = 0
- for item in itemIndexs {
- let indexpath = IndexPath(item: item, section: 0)
- let _toIndexPath = IndexPath(item: toIndex+cnt, section: 0)
- self.collectionView.animator().moveItem(at: indexpath, to: _toIndexPath)
-
- // 标记位置
- flagIndexs.insert(_toIndexPath.item)
- cnt += 1
- }
- } else if (itemIndexs.last! < toIndex) { // 往后拖放
- // 1,2 -> 3
- // 2->3, 1->2
-
- // 1,2 -> 4
- // 2->4, 1->3
-
- // 1,3 -> 4
- // 3->4, 1->3
- var cnt: Int = 0
- for item in itemIndexs.reversed() {
- let indexpath = IndexPath(item: item, section: 0)
- let _toIndexPath = IndexPath(item: toIndex-cnt, section: 0)
- self.collectionView.animator().moveItem(at: indexpath, to: _toIndexPath)
-
- // 标记位置
- flagIndexs.insert(_toIndexPath.item)
- cnt += 1
- }
- } else { // 往中间拖放(选中不连续)
- // 1,3 -> 2
- // 1->2, ...
- var cnt: Int = 0
- for item in itemIndexs {
- let indexpath = IndexPath(item: item, section: 0)
-
- if (cnt == 0) { // 第一个
- let _toIndexPath = IndexPath(item: toIndex, section: 0)
- self.collectionView.animator().moveItem(at: indexpath, to: _toIndexPath)
-
- flagIndexs.insert(toIndex)
- } else { // 第二个...
- if (indexpath.item == toIndex + cnt) { // 已在对应的位置
- // no doings
- flagIndexs.insert(toIndex+cnt)
- } else { // 需要移动
- let _toIndexPath = IndexPath(item: toIndex+cnt, section: 0)
- self.collectionView.animator().moveItem(at: indexpath, to: _toIndexPath)
-
- flagIndexs.insert(_toIndexPath.item)
- }
- }
- cnt += 1
- }
- }
-
- // 标记位置
- self._dragMoveFlagIndexs = flagIndexs
- return true
- }
-
- private func _doDragMoveEffect(to toIndexPath: IndexPath) -> Bool {
- if (self.dragedIndexPaths.isEmpty) {
- Swift.debugPrint("not find selected items.\(self.dragedIndexPaths)")
- return false
- }
- if (self.dragedIndexPaths.contains(toIndexPath) == false) { // 目标位置不在拖放数组里
- if (self._dragMoveFlagIndexs == nil) { // 第一次移动
- var itemIndexPaths = Set<IndexPath>()
- for indexpath in self.dragedIndexPaths {
- itemIndexPaths.insert(indexpath)
- }
- return self._moveItemsForDrag(at: itemIndexPaths, to: toIndexPath)
- } else { // 已有移动
- if (self._dragMoveFlagIndexs!.contains(toIndexPath.item) == false) {
- return self._moveItemsForDrag(at: self._dragMoveFlagIndexs!, to: toIndexPath.item)
- } else {
- Swift.debugPrint("drag... ")
- }
- }
- } else if (self._dragMoveFlagIndexs != nil) { // 目标位置在拖放数组里且已有移动
- if (self._dragMoveFlagIndexs!.contains(toIndexPath.item) == false) {
- return self._moveItemsForDrag(at: self._dragMoveFlagIndexs!, to: toIndexPath.item)
- } else {
- Swift.debugPrint("drag... ")
- }
- }
-
- return false
- }
- }
- // MARK: - NSCollectionViewDataSource, NSCollectionViewDelegate
- extension KMThumbnailView: NSCollectionViewDataSource {
- public func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
- if let items = self.delegate?.thumbnailView?(thumbanView: self, numberOfItemsInSection: section) {
- return items
- }
- return self.numberOfSections
- }
-
- func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
- if let item = self.delegate?.thumbnailView?(thumbanView: self, itemForRepresentedObjectAt: indexPath) {
- return item
- }
- return NSCollectionViewItem()
- }
- }
- // MARK: - NSCollectionViewDelegate
- extension KMThumbnailView: NSCollectionViewDelegate {
- func collectionView(_ collectionView: NSCollectionView, shouldSelectItemsAt indexPaths: Set<IndexPath>) -> Set<IndexPath> {
- if let lastSelectedIndexPath = collectionView.selectionIndexPaths.first {
- if NSApp.currentEvent?.modifierFlags.contains(.shift) == true {
- // Shift 键按住,进行连续多选
- let selectedIndexPaths = collectionView.selectionIndexPaths
- var allIndexPaths = Set<IndexPath>(selectedIndexPaths)
- // 获取两个 IndexPath 之间的所有 IndexPath
- let startIndex = lastSelectedIndexPath.item
- let endIndex = indexPaths.first?.item ?? startIndex
- let range = startIndex < endIndex ? startIndex...endIndex : endIndex...startIndex
- for index in range {
- let indexPath = IndexPath(item: index, section: lastSelectedIndexPath.section)
- allIndexPaths.insert(indexPath)
- }
- return allIndexPaths
- }
- }
- return indexPaths
- }
-
- func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {}
-
- func collectionView(_ collectionView: NSCollectionView, shouldDeselectItemsAt indexPaths: Set<IndexPath>) -> Set<IndexPath> {
- return indexPaths
- }
-
- func collectionView(_ collectionView: NSCollectionView, didDeselectItemsAt indexPaths: Set<IndexPath>) {}
-
- func collectionView(_ collectionView: NSCollectionView, canDragItemsAt indexPaths: Set<IndexPath>, with event: NSEvent) -> Bool {
- if let can = self.delegate?.thumbnailView?(thumbanView: self, canDragItemsAt: indexPaths, with: event) {
- return can
- }
- return true
- }
-
- func collectionView(_ collectionView: NSCollectionView, writeItemsAt indexPaths: Set<IndexPath>, to pasteboard: NSPasteboard) -> Bool {
- let data: Data = try! NSKeyedArchiver.archivedData(withRootObject: indexPaths, requiringSecureCoding: true)
- pasteboard.declareTypes([self.localForDraggedTypes], owner: self)
- pasteboard.setData(data, forType: self.localForDraggedTypes)
-
- self.dragedIndexPaths.removeAll()
- for indexPath in indexPaths {
- self.dragedIndexPaths.append(indexPath)
- }
- return true
- }
-
- func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItemsAt indexes: IndexSet) {
- self.delegate?.thumbnailView?(thumbanView: self, draggingSession: session, willBeginAt: screenPoint, forItemsAt: indexes)
- }
-
- func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, dragOperation operation: NSDragOperation) {
- self._dragMoveFlagIndexpath = nil
- self._dragMoveFlagIndexs = nil
- self.delegate?.thumbnailView?(thumbanView: self, draggingSession: session, endedAt: screenPoint, dragOperation: operation)
- }
-
- func collectionView(_ collectionView: NSCollectionView, validateDrop draggingInfo: NSDraggingInfo, proposedIndexPath proposedDropIndexPath: AutoreleasingUnsafeMutablePointer<NSIndexPath>, dropOperation proposedDropOperation: UnsafeMutablePointer<NSCollectionView.DropOperation>) -> NSDragOperation {
- let pboard = draggingInfo.draggingPasteboard
- if (pboard.availableType(from: [self.localForDraggedTypes]) != nil) {
- return .move
- } else if (pboard.availableType(from: [.localDraggedTypes]) != nil) {
- if (proposedDropOperation.pointee == .on && self.dragMoveEffectAnimated) {
- _ = self._doDragMoveEffect(to: proposedDropIndexPath.pointee as IndexPath)
- }
-
- return .move
- } else if ((pboard.availableType(from: [.fileURL])) != nil) {
- guard let pbItems = pboard.pasteboardItems else {
- return NSDragOperation(rawValue: 0)
- }
- guard let _allowedFileTypes = self.kmAllowedFileTypes else {
- return .generic
- }
-
- var hasValidFile = false
- for item in pbItems {
- guard let data = item.string(forType: .fileURL), let _url = URL(string: data) else {
- continue
- }
- let type = _url.pathExtension.lowercased()
- if (_allowedFileTypes.contains(type)) {
- hasValidFile = true
- break
- }
- }
-
- if (!hasValidFile) {
- return NSDragOperation(rawValue: 0)
- }
- }
-
- return .generic
- }
-
- func collectionView(_ collectionView: NSCollectionView, acceptDrop draggingInfo: NSDraggingInfo, indexPath: IndexPath, dropOperation: NSCollectionView.DropOperation) -> Bool {
- if let should = self.delegate?.thumbnailView?(thumbanView: self, shouldAcceptDrop: draggingInfo, indexPath: indexPath, dropOperation: dropOperation), !should {
- return should
- }
-
- let pboard = draggingInfo.draggingPasteboard
- if (pboard.availableType(from: [self.localForDraggedTypes]) != nil) {
- let dragInfo = [
- KMThumbnailViewDragInfoKey.draggingInfo.rawValue : draggingInfo,
- KMThumbnailViewDragInfoKey.dropOperation.rawValue : dropOperation
- ] as [Int : Any]
- self.delegate?.thumbnailView?(thumbanView: self, didDrag: self.dragedIndexPaths, indexpath: indexPath, dragInfo: dragInfo)
- self.dragedIndexPaths.removeAll()
- return true
- } else if (pboard.availableType(from: [.localDraggedTypes]) != nil) {
- var _dragIndexpaths = Set<IndexPath>()
- draggingInfo.enumerateDraggingItems(
- options: NSDraggingItemEnumerationOptions.concurrent,
- for: collectionView,
- classes: [NSPasteboardItem.self],
- searchOptions: [:],
- using: {(draggingItem, idx, stop) in
- if let pasteboardItem = draggingItem.item as? NSPasteboardItem {
- do {
- if let indexPathData = pasteboardItem.data(forType: .localDraggedTypes), let _indexPath =
- try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(indexPathData) as? IndexPath {
-
- _dragIndexpaths.insert(_indexPath)
- }
- } catch {
- Swift.debugPrint("failed to unarchive indexPath for dropped photo item.")
- }
- }
- })
-
- let dragInfo = [
- KMThumbnailViewDragInfoKey.draggingInfo.rawValue : draggingInfo,
- KMThumbnailViewDragInfoKey.dropOperation.rawValue : dropOperation
- ] as [Int : Any]
- self.delegate?.thumbnailView?(thumbanView: self, didDrag: _dragIndexpaths.sorted(), indexpath: indexPath, dragInfo: dragInfo)
- self.dragedIndexPaths.removeAll()
- return true
- } else if ((pboard.availableType(from: [.fileURL])) != nil) {
- var array: [URL] = []
- for item: NSPasteboardItem in pboard.pasteboardItems! {
- let string: String = item.string(forType: NSPasteboard.PasteboardType.fileURL)!
- let url = NSURL(string: string)
- array.append(url! as URL)
- }
-
- self.delegate?.thumbnailView?(thumbanView: self, didDragAddFiles: array, indexpath: indexPath)
- return true
- }
-
- return false
- }
- }
- // MARK: - NSCollectionViewDelegateFlowLayout
- extension KMThumbnailView: NSCollectionViewDelegateFlowLayout {
- func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
- if let size_ = self.delegate?.thumbnailView?(thumbanView: self, sizeForItemAt: indexPath) {
- return size_
- }
-
- return self.itemSize
- }
-
- func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
- if let minimumLineSpacing_ = self.delegate?.thumbnailView?(thumbanView: self, minimumLineSpacingForSectionAt: section) {
- return minimumLineSpacing_
- }
- return self.minimumLineSpacing
- }
-
- func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
- if let minimumInteritemSpacing_ = self.delegate?.thumbnailView?(thumbanView: self, minimumInteritemSpacingForSectionAt: section) {
- return minimumInteritemSpacing_
- }
- return self.minimumInteritemSpacing
- }
-
- func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, insetForSectionAt section: Int) -> NSEdgeInsets {
- if let inset = self.delegate?.thumbnailView?(thumbanView: self, insetForSectionAt: section) {
- return inset
- }
- return self.sectionInset
- }
- }
|