KMPDFThumbnailItem.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. //
  2. // KMPDFThumbnailItem.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by lxy on 2022/12/16.
  6. //
  7. import Cocoa
  8. let pageBoxBorder = 5
  9. let textBoxSpace = 2
  10. let textLabelHeight = 15
  11. typealias KMPDFThumbnailItemMouseDown = (_ view: KMPDFThumbnailItem, _ event: NSEvent) -> Void
  12. typealias KMPDFThumbnailItemHover = (_ view: KMPDFThumbnailItem, _ mouseEntered: Bool) -> Void
  13. typealias KMPDFThumbnailItemRightMouseDown = (_ view: KMPDFThumbnailItem, _ event: NSEvent) -> Void
  14. class KMPDFThumbnailItem: NSCollectionViewItem {
  15. lazy var pageBox : NSView = {
  16. let pageBox = NSView()
  17. pageBox.wantsLayer = true
  18. // pageBox.layer?.borderWidth = 1
  19. // pageBox.layer?.borderColor = NSColor.km_init(hex: "#CED0D4").cgColor
  20. // pageBox.layer?.cornerRadius = 2.0
  21. // pageBox.layer?.masksToBounds = true
  22. return pageBox
  23. }()
  24. lazy var textBox : NSView = {
  25. let textBox = NSView()
  26. return textBox
  27. }()
  28. lazy var pageTextLabel : NSTextField = {
  29. let pageTextLabel = NSTextField()
  30. pageTextLabel.isEditable = false
  31. pageTextLabel.isBordered = false
  32. pageTextLabel.isSelectable = false
  33. pageTextLabel.drawsBackground = false
  34. pageTextLabel.font = NSFont.SFProTextRegularFont(14)
  35. pageTextLabel.textColor = NSColor.km_init(hex: "#252629")
  36. return pageTextLabel
  37. }()
  38. lazy var pageSizeTextLabel : NSTextField = {
  39. let pageSizeTextLabel = NSTextField()
  40. pageSizeTextLabel.isEditable = false
  41. pageSizeTextLabel.isBordered = false
  42. pageSizeTextLabel.drawsBackground = false
  43. pageSizeTextLabel.font = NSFont.SFProTextRegularFont(14)
  44. pageSizeTextLabel.textColor = NSColor.km_init(hex: "#252629")
  45. return pageSizeTextLabel
  46. }()
  47. lazy var pageView = KMPDFThumbnialPageView()
  48. var page : CPDFPage = CPDFPage() {
  49. didSet {
  50. self.pageView.page = page
  51. self.updatePageState(page: page)
  52. }
  53. }
  54. var thumbnailView : KMPDFThumbnailView = KMPDFThumbnailView()
  55. var mouseDownAction: KMPDFThumbnailItemMouseDown?
  56. var rightMouseDownAction: KMPDFThumbnailItemRightMouseDown?
  57. var hoverCallBack: KMPDFThumbnailItemHover?
  58. var contentBox: KMBox?
  59. //注释状态
  60. var annotationShowState: KMAnnotationViewShowType = .none {
  61. didSet {
  62. if self.annotationShowState == .hidden {
  63. for annotation in self.page.annotations {
  64. if annotation.annotationShouldDisplay() == false {
  65. annotation.setHidden(true)
  66. }
  67. }
  68. } else {
  69. for annotation in self.page.annotations {
  70. annotation.setHidden(false)
  71. }
  72. }
  73. }
  74. }
  75. var hover: Bool = false {
  76. didSet {
  77. self.updateItemState()
  78. }
  79. }
  80. override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) {
  81. super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
  82. }
  83. required init?(coder: NSCoder) {
  84. fatalError("init(coder:) has not been implemented")
  85. }
  86. override func viewDidLoad() {
  87. super.viewDidLoad()
  88. self.view.addSubview(self.pageBox)
  89. self.view.wantsLayer = true
  90. self.view.layer?.cornerRadius = 8.0
  91. self.view.layer?.masksToBounds = true
  92. self.view.layer?.borderWidth = 1.0
  93. self.isSelected = false
  94. self.pageBox.addSubview(pageView)
  95. self.view.addSubview(self.textBox)
  96. self.textBox.addSubview(self.pageTextLabel)
  97. self.textBox.addSubview(self.pageSizeTextLabel)
  98. self.addContentBox()
  99. }
  100. //MARK: Accessors
  101. override var isSelected: Bool {
  102. get {
  103. return super.isSelected
  104. }
  105. set {
  106. super.isSelected = newValue
  107. // if (newValue) {
  108. // self.view.layer?.backgroundColor = NSColor.km_init(hex: "#CED0D4", alpha: 0.6).cgColor
  109. // self.view.layer?.borderColor = NSColor.km_init(hex: "#CED0D4").cgColor
  110. // } else {
  111. // self.view.layer?.backgroundColor = NSColor.clear.cgColor
  112. // self.view.layer?.borderColor = NSColor.clear.cgColor
  113. // }
  114. self.updateItemState()
  115. }
  116. }
  117. func updatePageState(page: CPDFPage!) {
  118. if page != nil {
  119. let index = page.document.index(for: page) + 1
  120. self.pageTextLabel.stringValue = "\(index)"
  121. let bounds = self.page.bounds
  122. let rect = self.page.bounds(for: .cropBox)
  123. let width = KMPageSizeTool.conversion(withUnit: "mm", value: rect.width/595*210)
  124. let height = KMPageSizeTool.conversion(withUnit: "mm", value: rect.height/842*297)
  125. // if page.rotation == 90 || page.rotation == 270 {
  126. // self.pageSizeTextLabel.stringValue = "\(Int(bounds.size.height))*\(Int(bounds.size.width)) mm"
  127. // } else {
  128. // self.pageSizeTextLabel.stringValue = "\(Int(bounds.size.width))*\(Int(bounds.size.height)) mm"
  129. // }
  130. if (page.rotation == 90 || page.rotation == 270 || page.rotation == -90 || page.rotation == -270) {
  131. self.pageSizeTextLabel.stringValue = String(format: "%.f * %.f \(NSLocalizedString("mm", comment: ""))", height.stringToCGFloat(), width.stringToCGFloat())
  132. } else {
  133. self.pageSizeTextLabel.stringValue = String(format: "%.f * %.f \(NSLocalizedString("mm", comment: ""))", width.stringToCGFloat(), height.stringToCGFloat())
  134. }
  135. self.updateFrame()
  136. self.updateItemState()
  137. }
  138. }
  139. class func sizeToFit(size:NSSize,page:CPDFPage,isShow:Bool) -> CGFloat {
  140. var height = 0
  141. var bounds = page.bounds
  142. let transform = page.transform()
  143. bounds = bounds.applying(transform)
  144. var newSize = CGSize(width: size.width, height: size.height)
  145. if bounds.size.width > bounds.size.height {
  146. newSize.height = size.width * bounds.size.height / bounds.size.width
  147. } else {
  148. newSize.width = size.height * bounds.size.width / bounds.size.height
  149. }
  150. height = height + Int(size.height) + pageBoxBorder
  151. if isShow {
  152. height = height + 30 + textBoxSpace
  153. } else {
  154. height = height + 15 + textBoxSpace
  155. }
  156. return CGFloat(height)
  157. }
  158. func updateFrame () {
  159. let viewWidth: CGFloat = NSWidth(self.view.bounds)
  160. let viewHeight: CGFloat = NSHeight(self.view.bounds)
  161. let border: CGFloat = CGFloat(pageBoxBorder)
  162. var bounds = self.page.bounds
  163. let transform = self.page.transform()
  164. bounds = bounds.applying(transform)
  165. var size = self.thumbnailView.thumbnailSzie
  166. if bounds.size.width > bounds.size.height {
  167. if (bounds.size.width > 0) {
  168. size.height = size.width * bounds.size.height / bounds.size.width
  169. }
  170. } else {
  171. if (bounds.size.height > 0) {
  172. size.width = size.height * bounds.size.width / bounds.size.height
  173. }
  174. }
  175. size.width = size.width + CGFloat(border)
  176. size.height = size.height + CGFloat(border)
  177. let height = textLabelHeight
  178. let labelSize = NSMakeSize(size.width, CGFloat(MAXFLOAT))
  179. if self.thumbnailView.isShowPageSize == false {
  180. let pageTextLabelSize = self.pageTextLabel.sizeThatFits(labelSize)
  181. self.pageSizeTextLabel.sizeToFit()
  182. let pageSizeTextLabelSize = self.pageSizeTextLabel.frame.size
  183. let width = max(pageTextLabelSize.width, pageSizeTextLabelSize.width) + 5
  184. self.pageSizeTextLabel.isHidden = false
  185. self.pageSizeTextLabel.frame = NSMakeRect((width - pageSizeTextLabelSize.width) / 2.0, 6, pageSizeTextLabelSize.width, CGFloat(height));
  186. self.pageTextLabel.frame = NSMakeRect((width - pageTextLabelSize.width) / 2.0, self.pageSizeTextLabel.frame.maxY+5, pageTextLabelSize.width, CGFloat(height));
  187. let textBoxHeight: CGFloat = 44
  188. self.textBox.frame = NSMakeRect((self.view.frame.size.width - width) / 2.0, CGFloat(textBoxSpace), width, textBoxHeight)
  189. } else {
  190. let pageTextLabelSize = self.pageTextLabel.sizeThatFits(labelSize)
  191. let width = pageTextLabelSize.width + 5
  192. self.pageSizeTextLabel.isHidden = true
  193. self.pageTextLabel.frame = NSMakeRect((width - pageTextLabelSize.width) / 2.0, 6, pageTextLabelSize.width, CGFloat(height));
  194. let textBoxHeight: CGFloat = 22
  195. self.textBox.frame = NSMakeRect((self.view.frame.size.width - width) / 2.0, CGFloat(textBoxSpace), width, textBoxHeight)
  196. }
  197. let margin: CGFloat = 16
  198. let pageBoxY: CGFloat = self.textBox.frame.maxY+5
  199. let pageBoxW: CGFloat = viewWidth-margin*2
  200. let pageBoxH: CGFloat = viewHeight-pageBoxY-margin
  201. self.pageBox.frame = NSMakeRect(margin, pageBoxY, pageBoxW, pageBoxH)
  202. var pageX: CGFloat = (NSWidth(self.pageBox.frame)-size.width)*0.5
  203. if (pageX < 0) {
  204. let tempWidth = size.width + pageX * 2
  205. let scale = tempWidth / size.width
  206. size.width = size.width * scale
  207. size.height = size.height * scale
  208. }
  209. pageX = (NSWidth(self.pageBox.frame)-size.width)*0.5
  210. let pageY: CGFloat = (NSHeight(self.pageBox.frame)-size.height)*0.5
  211. self.pageView.frame = NSMakeRect(pageX, pageY, size.width, size.height)
  212. }
  213. func updateItemState() {
  214. if isSelected {
  215. self.view.layer?.backgroundColor = NSColor.km_init(hex: "#CED0D4", alpha: 0.6).cgColor
  216. self.view.layer?.borderColor = NSColor.km_init(hex: "#CED0D4").cgColor
  217. } else if hover {
  218. self.view.layer?.backgroundColor = NSColor.km_init(hex: "#EDEEF0").cgColor
  219. self.view.layer?.borderColor = NSColor.clear.cgColor
  220. } else {
  221. self.view.layer?.backgroundColor = NSColor.clear.cgColor
  222. self.view.layer?.borderColor = NSColor.clear.cgColor
  223. }
  224. }
  225. func addContentBox() {
  226. if self.contentBox == nil {
  227. let rect = self.view.bounds
  228. self.contentBox?.wantsLayer = true
  229. self.contentBox?.layer?.masksToBounds = true
  230. self.contentBox = KMBox(frame: rect)
  231. self.contentBox?.borderWidth = 0
  232. // self.box?.borderColor = NSColor.km_init(hex: "#EDEEF0")
  233. self.contentBox?.layer?.cornerRadius = 8
  234. self.contentBox?.boxType = .custom
  235. self.view.addSubview(self.contentBox!, positioned: NSWindow.OrderingMode.below, relativeTo: self.view)
  236. self.contentBox?.autoresizingMask = [.width, .height]
  237. self.contentBox?.moveCallback = { [unowned self] (mouseEntered, mouseBox) in
  238. self.hoverCallBack?(self, mouseEntered)
  239. }
  240. self.contentBox?.rightDownCallback = { [unowned self] (downEntered, mouseBox, event) in
  241. self.rightMouseDownAction?(self, event)
  242. }
  243. }
  244. }
  245. override func mouseMoved(with event: NSEvent) {
  246. super.mouseMoved(with: event)
  247. }
  248. override func mouseDown(with event: NSEvent) {
  249. super.mouseDown(with: event)
  250. guard let callBack = mouseDownAction else { return }
  251. callBack(self, event)
  252. }
  253. }
  254. extension KMPDFThumbnailItem: KMReusable {}