KMPageNumberDisplayView.swift 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //
  2. // KMPageNumberDisplayView.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by lizhe on 2023/4/25.
  6. //
  7. import Cocoa
  8. protocol KMPageNumberDisplayViewDelegate: NSObject {
  9. func gotoPageIndex(view: KMPageNumberDisplayView, pageIndex: Int)
  10. func updateWidth(view: KMPageNumberDisplayView, width: CGFloat)
  11. }
  12. class KMPageNumberDisplayView: KMBaseXibView {
  13. @IBOutlet weak var totalPageCountLabel: NSTextField!
  14. @IBOutlet weak var pageWidthConstraint: NSLayoutConstraint!
  15. @IBOutlet weak var lineLabel: NSTextFieldCell!
  16. @IBOutlet weak var currentPageIndexLabel: FocusAwareTextField!
  17. @IBOutlet weak var currentPageContentView: NSView!
  18. @IBOutlet weak var pageLabelConstraint: NSLayoutConstraint!
  19. var displayType: KMPreferencePageIndicatorDisplayType? {
  20. didSet {
  21. self.updateViewDispaly()
  22. }
  23. }
  24. var timer: Timer?
  25. weak var delegate: KMPageNumberDisplayViewDelegate?
  26. var currentPageIndex: Int? {
  27. didSet {
  28. let string = (currentPageIndex! + 1).description
  29. self.currentPageIndexLabel.stringValue = string
  30. self.updateUI()
  31. }
  32. }
  33. var totalPagesCount: Int? {
  34. didSet {
  35. self.totalPageCountLabel.stringValue = totalPagesCount?.description ?? "1"
  36. self.updateUI()
  37. }
  38. }
  39. var hover: Bool = false {
  40. didSet{
  41. self.updateViewDispaly()
  42. }
  43. }
  44. var isEdit: Bool = false {
  45. didSet {
  46. self.currentPageIndexLabel.isEditable = isEdit
  47. if isEdit {
  48. _ = self.currentPageIndexLabel.becomeFirstResponder()
  49. self.currentPageIndexLabel.currentEditor()?.selectAll(nil)
  50. }
  51. self.updateUI()
  52. }
  53. }
  54. deinit {
  55. self.dismiss()
  56. }
  57. override func draw(_ dirtyRect: NSRect) {
  58. super.draw(dirtyRect)
  59. // Drawing code here.
  60. }
  61. override func setup() {
  62. self.backgroundColor(NSColor.km_init(hex: "#36383B"))
  63. self.shadow = NSShadow()
  64. self.wantsLayer = true
  65. self.layer?.shadowColor = NSColor.km_init(hex: "#000000", alpha: 0.16).cgColor
  66. self.layer?.shadowOffset = CGSize(width: 0, height: -2)
  67. self.layer?.shadowRadius = 8
  68. self.layer?.shadowOpacity = 1
  69. self.layer?.cornerRadius = 4
  70. self.currentPageIndexLabel.delegate = self
  71. }
  72. //刷新界面UI 和 数据
  73. override func reloadData() {
  74. }
  75. override func updateLanguage() {
  76. }
  77. override func updateUI() {
  78. // NSString(string: self.currentPageLabel.stringValue).boundingRect(with: NSSize(width: 1000, height: 1000)).size.width + 8
  79. self.totalPageCountLabel.textColor = NSColor.km_init(hex: "#FFFFFF")
  80. self.totalPageCountLabel.font = NSFont.SFProTextRegularFont(12.0)
  81. self.lineLabel.textColor = NSColor.km_init(hex: "#FFFFFF")
  82. self.lineLabel.font = NSFont.SFProTextRegularFont(12.0)
  83. if isEdit {
  84. currentPageIndexLabel.textColor = NSColor.km_init(hex: "#252629")
  85. currentPageIndexLabel.font = NSFont.SFProTextRegularFont(12.0)
  86. currentPageContentView.backgroundColor(NSColor.km_init(hex: "#FFFFFF"))
  87. currentPageContentView.border(NSColor.km_init(hex: "#DFE1E5"), 1, 4)
  88. } else {
  89. currentPageIndexLabel.textColor = NSColor.km_init(hex: "#FFFFFF")
  90. currentPageIndexLabel.font = NSFont.SFProTextRegularFont(12.0)
  91. currentPageContentView.backgroundColor(NSColor.km_init(hex: "#FFFFFF", alpha: 0))
  92. currentPageContentView.border(NSColor.km_init(hex: "#DFE1E5"), 0, 4)
  93. }
  94. self.delegate?.updateWidth(view: self, width: self.fetchWith(edit: self.isEdit))
  95. }
  96. override func resetData() {
  97. }
  98. override func addNotification() {
  99. }
  100. override func removeNotification() {
  101. }
  102. func fetchWith(edit: Bool = false) -> CGFloat {
  103. let currentIndexString: NSString = self.currentPageIndexLabel.stringValue as NSString
  104. let totalPageCountString: NSString = self.totalPageCountLabel.stringValue as NSString
  105. let attributes = [NSAttributedString.Key.font : NSFont.SFProTextRegularFont(12.0), NSAttributedString.Key.foregroundColor: NSColor.km_init(hex: "#FFFFFF")]
  106. let currentIndexStringWidth = currentIndexString.boundingRect(with: CGSize(width: 100, height: 36), attributes: attributes).width
  107. let totalPageCountStringWidth = totalPageCountString.boundingRect(with: CGSize(width: 100, height: 36), attributes: attributes).width
  108. var width = 16 + currentIndexStringWidth + 8 + 4 + 8 + totalPageCountStringWidth + 16
  109. if edit {
  110. self.pageWidthConstraint.constant = currentIndexStringWidth + 40
  111. self.pageLabelConstraint.constant = currentIndexStringWidth + 24
  112. width += 40
  113. } else {
  114. self.pageWidthConstraint.constant = currentIndexStringWidth
  115. self.pageLabelConstraint.constant = currentIndexStringWidth
  116. }
  117. return width
  118. }
  119. }
  120. //MARK: mouse
  121. extension KMPageNumberDisplayView {
  122. override func mouseDown(with event: NSEvent) {
  123. KMPrint("mouseDown")
  124. if !self.isEdit {
  125. self.isEdit = true
  126. self.delegate?.updateWidth(view: self, width: self.fetchWith(edit: self.isEdit))
  127. }
  128. }
  129. }
  130. //MARK:
  131. extension KMPageNumberDisplayView: NSTextFieldDelegate {
  132. func controlTextDidEndEditing(_ obj: Notification) {
  133. if obj.object is FocusAwareTextField {
  134. self.toPageIndex()
  135. }
  136. }
  137. func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
  138. switch commandSelector {
  139. case #selector(NSResponder.insertNewline(_:)):
  140. if let _ = control as? NSTextField {
  141. //当当前TextField按下enter
  142. if (textView.string == self.currentPageIndexLabel.stringValue) {
  143. KMPrint("按下 enter")
  144. self.isEdit = false
  145. self.toPageIndex()
  146. }
  147. }
  148. return true
  149. default:
  150. return false
  151. }
  152. }
  153. func toPageIndex() {
  154. var index = (self.currentPageIndex ?? 0) + 1
  155. if Int(self.currentPageIndexLabel.stringValue) != nil {
  156. index = min(max(1, Int(self.currentPageIndexLabel.stringValue)!), totalPagesCount!)
  157. }
  158. self.currentPageIndexLabel.stringValue = String(index)
  159. self.delegate?.gotoPageIndex(view: self, pageIndex: index - 1)
  160. self.updateUI()
  161. }
  162. }
  163. //MARK: In out
  164. extension KMPageNumberDisplayView {
  165. @objc fileprivate func inView() {
  166. self.dismiss()
  167. NSAnimationContext.runAnimationGroup { NSAnimationContext in
  168. self.animator().alphaValue = 1
  169. }
  170. }
  171. @objc fileprivate func outView() {
  172. NSAnimationContext.runAnimationGroup { NSAnimationContext in
  173. self.animator().alphaValue = 0
  174. self.dismiss()
  175. self.isEdit = false
  176. }
  177. }
  178. func reset() {
  179. self.dismiss()
  180. self.show()
  181. }
  182. func show(type: KMPreferencePageIndicatorDisplayType = .automatic) {
  183. self.displayType = type
  184. }
  185. func dismiss() {
  186. self.timer?.invalidate()
  187. self.timer = nil
  188. }
  189. func updateViewDispaly() {
  190. var type = self.displayType
  191. if hover {
  192. type = .always
  193. }
  194. if type == .automatic {
  195. if self.timer != nil {
  196. self.dismiss()
  197. }
  198. self.inView()
  199. self.timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(outView), userInfo: nil, repeats: true)
  200. } else if type == .never {
  201. self.dismiss()
  202. } else if type == .always {
  203. self.inView()
  204. }
  205. }
  206. }