// // KMPDFThumbnailItem.swift // PDF Reader Pro // // Created by lxy on 2022/12/16. // import Cocoa let pageBoxBorder = 5 let textBoxSpace = 2 let textLabelHeight = 15 typealias KMPDFThumbnailItemMouseDown = (_ view: KMPDFThumbnailItem, _ event: NSEvent) -> Void typealias KMPDFThumbnailItemHover = (_ view: KMPDFThumbnailItem, _ mouseEntered: Bool) -> Void typealias KMPDFThumbnailItemRightMouseDown = (_ view: KMPDFThumbnailItem, _ event: NSEvent) -> Void class KMPDFThumbnailItem: NSCollectionViewItem { lazy var pageBox : NSView = { let pageBox = NSView() pageBox.wantsLayer = true // pageBox.layer?.borderWidth = 1 // pageBox.layer?.borderColor = NSColor.km_init(hex: "#CED0D4").cgColor // pageBox.layer?.cornerRadius = 2.0 // pageBox.layer?.masksToBounds = true return pageBox }() lazy var textBox : NSView = { let textBox = NSView() return textBox }() lazy var pageTextLabel : NSTextField = { let pageTextLabel = NSTextField() pageTextLabel.isEditable = false pageTextLabel.isBordered = false pageTextLabel.isSelectable = false pageTextLabel.drawsBackground = false pageTextLabel.font = NSFont.SFProTextRegularFont(14) pageTextLabel.textColor = NSColor.km_init(hex: "#252629") return pageTextLabel }() lazy var pageSizeTextLabel : NSTextField = { let pageSizeTextLabel = NSTextField() pageSizeTextLabel.isEditable = false pageSizeTextLabel.isBordered = false pageSizeTextLabel.drawsBackground = false pageSizeTextLabel.font = NSFont.SFProTextRegularFont(14) pageSizeTextLabel.textColor = NSColor.km_init(hex: "#252629") return pageSizeTextLabel }() lazy var pageView = KMPDFThumbnialPageView() var page : CPDFPage = CPDFPage() { didSet { self.pageView.page = page self.updatePageState(page: page) } } var thumbnailView : KMPDFThumbnailView = KMPDFThumbnailView() var mouseDownAction: KMPDFThumbnailItemMouseDown? var rightMouseDownAction: KMPDFThumbnailItemRightMouseDown? var hoverCallBack: KMPDFThumbnailItemHover? var contentBox: KMBox? //注释状态 var annotationShowState: KMAnnotationViewShowType = .none { didSet { if self.annotationShowState == .hidden { for annotation in self.page.annotations { if annotation.annotationShouldDisplay() == false { annotation.setHidden(true) } } } else { for annotation in self.page.annotations { annotation.setHidden(false) } } } } var hover: Bool = false { didSet { self.updateItemState() } } override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() self.view.addSubview(self.pageBox) self.view.wantsLayer = true self.view.layer?.cornerRadius = 8.0 self.view.layer?.masksToBounds = true self.view.layer?.borderWidth = 1.0 self.isSelected = false self.pageBox.addSubview(pageView) self.view.addSubview(self.textBox) self.textBox.addSubview(self.pageTextLabel) self.textBox.addSubview(self.pageSizeTextLabel) self.addContentBox() } //MARK: Accessors override var isSelected: Bool { get { return super.isSelected } set { super.isSelected = newValue // if (newValue) { // self.view.layer?.backgroundColor = NSColor.km_init(hex: "#CED0D4", alpha: 0.6).cgColor // self.view.layer?.borderColor = NSColor.km_init(hex: "#CED0D4").cgColor // } else { // self.view.layer?.backgroundColor = NSColor.clear.cgColor // self.view.layer?.borderColor = NSColor.clear.cgColor // } self.updateItemState() } } func updatePageState(page: CPDFPage!) { if page != nil { let index = page.document.index(for: page) + 1 self.pageTextLabel.stringValue = "\(index)" let bounds = self.page.bounds let rect = self.page.bounds(for: .cropBox) let width = KMPageSizeTool.conversion(withUnit: "mm", value: rect.width/595*210) let height = KMPageSizeTool.conversion(withUnit: "mm", value: rect.height/842*297) // if page.rotation == 90 || page.rotation == 270 { // self.pageSizeTextLabel.stringValue = "\(Int(bounds.size.height))*\(Int(bounds.size.width)) mm" // } else { // self.pageSizeTextLabel.stringValue = "\(Int(bounds.size.width))*\(Int(bounds.size.height)) mm" // } if (page.rotation == 90 || page.rotation == 270 || page.rotation == -90 || page.rotation == -270) { self.pageSizeTextLabel.stringValue = String(format: "%.f * %.f \(NSLocalizedString("mm", comment: ""))", height.stringToCGFloat(), width.stringToCGFloat()) } else { self.pageSizeTextLabel.stringValue = String(format: "%.f * %.f \(NSLocalizedString("mm", comment: ""))", width.stringToCGFloat(), height.stringToCGFloat()) } self.updateFrame() self.updateItemState() } } class func sizeToFit(size:NSSize,page:CPDFPage,isShow:Bool) -> CGFloat { var height = 0 var bounds = page.bounds let transform = page.transform() bounds = bounds.applying(transform) var newSize = CGSize(width: size.width, height: size.height) if bounds.size.width > bounds.size.height { newSize.height = size.width * bounds.size.height / bounds.size.width } else { newSize.width = size.height * bounds.size.width / bounds.size.height } height = height + Int(size.height) + pageBoxBorder if isShow { height = height + 30 + textBoxSpace } else { height = height + 15 + textBoxSpace } return CGFloat(height) } func updateFrame () { let viewWidth: CGFloat = NSWidth(self.view.bounds) let viewHeight: CGFloat = NSHeight(self.view.bounds) let border: CGFloat = CGFloat(pageBoxBorder) var bounds = self.page.bounds let transform = self.page.transform() bounds = bounds.applying(transform) var size = self.thumbnailView.thumbnailSzie if bounds.size.width > bounds.size.height { if (bounds.size.width > 0) { size.height = size.width * bounds.size.height / bounds.size.width } } else { if (bounds.size.height > 0) { size.width = size.height * bounds.size.width / bounds.size.height } } size.width = size.width + CGFloat(border) size.height = size.height + CGFloat(border) let height = textLabelHeight let labelSize = NSMakeSize(size.width, CGFloat(MAXFLOAT)) if self.thumbnailView.isShowPageSize == false { let pageTextLabelSize = self.pageTextLabel.sizeThatFits(labelSize) self.pageSizeTextLabel.sizeToFit() let pageSizeTextLabelSize = self.pageSizeTextLabel.frame.size let width = max(pageTextLabelSize.width, pageSizeTextLabelSize.width) + 5 self.pageSizeTextLabel.isHidden = false self.pageSizeTextLabel.frame = NSMakeRect((width - pageSizeTextLabelSize.width) / 2.0, 6, pageSizeTextLabelSize.width, CGFloat(height)); self.pageTextLabel.frame = NSMakeRect((width - pageTextLabelSize.width) / 2.0, self.pageSizeTextLabel.frame.maxY+5, pageTextLabelSize.width, CGFloat(height)); let textBoxHeight: CGFloat = 44 self.textBox.frame = NSMakeRect((self.view.frame.size.width - width) / 2.0, CGFloat(textBoxSpace), width, textBoxHeight) } else { let pageTextLabelSize = self.pageTextLabel.sizeThatFits(labelSize) let width = pageTextLabelSize.width + 5 self.pageSizeTextLabel.isHidden = true self.pageTextLabel.frame = NSMakeRect((width - pageTextLabelSize.width) / 2.0, 6, pageTextLabelSize.width, CGFloat(height)); let textBoxHeight: CGFloat = 22 self.textBox.frame = NSMakeRect((self.view.frame.size.width - width) / 2.0, CGFloat(textBoxSpace), width, textBoxHeight) } let margin: CGFloat = 16 let pageBoxY: CGFloat = self.textBox.frame.maxY+5 let pageBoxW: CGFloat = viewWidth-margin*2 let pageBoxH: CGFloat = viewHeight-pageBoxY-margin self.pageBox.frame = NSMakeRect(margin, pageBoxY, pageBoxW, pageBoxH) var pageX: CGFloat = (NSWidth(self.pageBox.frame)-size.width)*0.5 if (pageX < 0) { let tempWidth = size.width + pageX * 2 let scale = tempWidth / size.width size.width = size.width * scale size.height = size.height * scale } pageX = (NSWidth(self.pageBox.frame)-size.width)*0.5 let pageY: CGFloat = (NSHeight(self.pageBox.frame)-size.height)*0.5 self.pageView.frame = NSMakeRect(pageX, pageY, size.width, size.height) } func updateItemState() { if isSelected { self.view.layer?.backgroundColor = NSColor.km_init(hex: "#CED0D4", alpha: 0.6).cgColor self.view.layer?.borderColor = NSColor.km_init(hex: "#CED0D4").cgColor } else if hover { self.view.layer?.backgroundColor = NSColor.km_init(hex: "#EDEEF0").cgColor self.view.layer?.borderColor = NSColor.clear.cgColor } else { self.view.layer?.backgroundColor = NSColor.clear.cgColor self.view.layer?.borderColor = NSColor.clear.cgColor } } func addContentBox() { if self.contentBox == nil { let rect = self.view.bounds self.contentBox?.wantsLayer = true self.contentBox?.layer?.masksToBounds = true self.contentBox = KMBox(frame: rect) self.contentBox?.borderWidth = 0 // self.box?.borderColor = NSColor.km_init(hex: "#EDEEF0") self.contentBox?.layer?.cornerRadius = 8 self.contentBox?.boxType = .custom self.view.addSubview(self.contentBox!, positioned: NSWindow.OrderingMode.below, relativeTo: self.view) self.contentBox?.autoresizingMask = [.width, .height] self.contentBox?.moveCallback = { [unowned self] (mouseEntered, mouseBox) in self.hoverCallBack?(self, mouseEntered) } self.contentBox?.rightDownCallback = { [unowned self] (downEntered, mouseBox, event) in self.rightMouseDownAction?(self, event) } } } override func mouseMoved(with event: NSEvent) { super.mouseMoved(with: event) } override func mouseDown(with event: NSEvent) { super.mouseDown(with: event) guard let callBack = mouseDownAction else { return } callBack(self, event) } } extension KMPDFThumbnailItem: KMReusable {}