KMNoteFooterCellView.swift 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. //
  2. // KMNoteFooterCellView.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by User-Tangchao on 2024/9/19.
  6. //
  7. import Cocoa
  8. import KMComponentLibrary
  9. class KMNoteFooterCellView: NSTableCellView, NibLoadable {
  10. @IBOutlet weak var replyBox: NSBox!
  11. @IBOutlet weak var inputBox: KMBox!
  12. @IBOutlet weak var inputTextF: KMTextField!
  13. @IBOutlet weak var replyButton: NSButton!
  14. @IBOutlet weak var cancelButton: NSButton!
  15. @IBOutlet weak var replyButtonBox: NSBox!
  16. @IBOutlet weak var operationBox: NSBox!
  17. @IBOutlet weak var operationIv: NSImageView!
  18. @IBOutlet weak var operationButton: NSButton!
  19. @IBOutlet weak var operationIvHover: KMCoverButton!
  20. @IBOutlet weak var inputBoxHeightConst: NSLayoutConstraint!
  21. @IBOutlet weak var replyButtonTopConst: NSLayoutConstraint!
  22. private lazy var inputRespButton_: NSButton = {
  23. let view = NSButton()
  24. view.isBordered = false
  25. view.title = KMLocalizedString("")
  26. view.target = self
  27. view.action = #selector(_inputRespButtonAction)
  28. return view
  29. }()
  30. var itemClick: KMCommonClickBlock?
  31. var inputDidChanged: KMValueDidChangeBlock?
  32. var model: KMBotaAnnotationFooterModel?
  33. private var flag_ = false
  34. override func draw(_ dirtyRect: NSRect) {
  35. super.draw(dirtyRect)
  36. // Drawing code here.
  37. }
  38. override func awakeFromNib() {
  39. super.awakeFromNib()
  40. self.flag_ = false
  41. // self.replyBox.fillColor = .red
  42. self.inputBox.cornerRadius = 0
  43. self.inputBox.moveCallback = { [weak self] enter, theBox in
  44. if enter {
  45. theBox.borderColor = NSColor.km_init(hex: "#1770F4")
  46. } else {
  47. // let focus = theBox.window?.firstResponder == self?.inputTextF
  48. let focus = self?.flag_ ?? false
  49. if focus == false {
  50. theBox.borderColor = NSColor(white: 0, alpha: 0.2)
  51. }
  52. }
  53. }
  54. self.inputBox.downCallback = { [weak self] enter, theBox, _ in
  55. theBox.window?.makeFirstResponder(self?.inputTextF)
  56. }
  57. self.inputTextF.drawsBackground = false
  58. self.inputTextF.isBordered = false
  59. self.inputTextF.isBezeled = false
  60. self.inputTextF.focusRingType = .none
  61. self.inputTextF.backgroundColor = .clear
  62. self.inputTextF.wantsLayer = true
  63. self.inputTextF.layer?.backgroundColor = .clear
  64. self.inputTextF.delegate = self
  65. let cell = self.inputTextF.cell as? NSTextFieldCell
  66. self.inputTextF.textColor = KMAppearance.titleColor()
  67. self.inputTextF.firstResponderHandler = { [weak self] result in
  68. self?.flag_ = result
  69. for sv in self?.inputTextF.subviews ?? [] {
  70. for childsv in sv.subviews {
  71. if let data = childsv as? NSTextView {
  72. data.backgroundColor = .clear
  73. }
  74. }
  75. }
  76. if result {
  77. self?.inputBox.borderColor = NSColor.km_init(hex: "#1770F4")
  78. self?.inputRespButton_.isHidden = true
  79. if let range = self?.inputTextF.currentEditor()?.selectedRange {
  80. self?.inputTextF.currentEditor()?.selectedRange = NSMakeRange(range.length, 0)
  81. }
  82. } else {
  83. if KMAppearance.isDarkMode() {
  84. self?.inputBox.borderColor = NSColor(hex: "#56585A")
  85. } else {
  86. self?.inputBox.borderColor = NSColor(white: 0, alpha: 0.2)
  87. }
  88. self?.inputRespButton_.isHidden = false
  89. }
  90. }
  91. self.inputBox.contentView?.addSubview(self.inputRespButton_)
  92. self.inputRespButton_.frame = self.inputBox.contentView?.bounds ?? .zero
  93. self.inputRespButton_.autoresizingMask = [.width, .height]
  94. self.replyButton.title = KMLocalizedString("Done")
  95. self.replyButton.wantsLayer = true
  96. self.replyButtonBox.cornerRadius = 1
  97. self.replyButtonBox.borderWidth = 0
  98. self.replyButton.target = self
  99. self.replyButton.action = #selector(replyAction)
  100. self.cancelButton.title = KMLocalizedString("Cancel")
  101. self.cancelButton.target = self
  102. self.cancelButton.action = #selector(cancelAction)
  103. self.operationBox.borderWidth = 0
  104. self.operationIv.image = NSImage(named: "KMImageNameBotaNoteOpration")
  105. self.operationButton.title = ""
  106. self.operationButton.target = self
  107. self.operationButton.action = #selector(operationAction)
  108. self.operationIvHover.wantsLayer = true
  109. self.operationIvHover.layer?.cornerRadius = 4
  110. self.operationIvHover.coverAction = { btn, act in
  111. if act == .enter {
  112. btn.layer?.backgroundColor = NSColor(hex: "#477EDE").withAlphaComponent(0.1).cgColor
  113. } else if act == .exit {
  114. btn.layer?.backgroundColor = .clear
  115. }
  116. }
  117. self.updateUI(expand: false, animated: false)
  118. self.updateViewUI()
  119. NotificationCenter.default.addObserver(self, selector: #selector(updateViewUI), name: APPAppearanceChangedNotificationName, object: nil)
  120. }
  121. func updateUI(expand: Bool, animated: Bool) {
  122. if expand {
  123. // 64
  124. if animated {
  125. self.inputBoxHeightConst.animator().constant = 64+6
  126. } else {
  127. self.inputBoxHeightConst.constant = 64+6
  128. }
  129. // 12
  130. self.replyBox.isHidden = false
  131. } else {
  132. // 64
  133. if animated {
  134. self.inputBoxHeightConst.animator().constant = 0
  135. } else {
  136. self.inputBoxHeightConst.constant = 0
  137. }
  138. self.replyBox.isHidden = true
  139. }
  140. }
  141. @objc func replyAction(_ sender: NSButton) {
  142. self.itemClick?(3, self.inputTextF.stringValue)
  143. }
  144. @objc func cancelAction(_ sender: NSButton) {
  145. self.itemClick?(4)
  146. }
  147. @objc func commentAction(_ sender: NSButton) {
  148. self.itemClick?(1)
  149. }
  150. @objc func operationAction(_ sender: NSButton) {
  151. self.itemClick?(2, sender)
  152. }
  153. @objc private func _inputRespButtonAction() {
  154. self.window?.makeFirstResponder(self.inputTextF)
  155. self.inputRespButton_.isHidden = true
  156. }
  157. @objc func updateViewUI() {
  158. if KMAppearance.isDarkMode() {
  159. self.inputBox.fillColor = NSColor(hex: "#393C3E")
  160. self.inputBox.borderColor = NSColor(hex: "#56585A")
  161. } else {
  162. self.inputBox.fillColor = .white
  163. self.inputBox.borderColor = NSColor(white: 0, alpha: 0.2)
  164. }
  165. let buttonColor = ComponentLibrary.shared.getComponentColorFromKey("comp-button/textPrimary-colorText-nor")
  166. let buttonFont = ComponentLibrary.shared.getFontFromKey("mac/body-m-regular")
  167. self.replyButton.setTitleColor(color: buttonColor, font: buttonFont)
  168. self.cancelButton.setTitleColor(color: buttonColor, font: buttonFont)
  169. }
  170. override func updateLayer() {
  171. super.updateLayer()
  172. self.updateViewUI()
  173. }
  174. }
  175. extension KMNoteFooterCellView: NSTextFieldDelegate {
  176. func controlTextDidEndEditing(_ obj: Notification) {
  177. if self.inputTextF.isEqual(to: obj.object) {
  178. if KMAppearance.isDarkMode() {
  179. self.inputBox.borderColor = NSColor(hex: "#56585A")
  180. } else {
  181. self.inputBox.borderColor = NSColor(white: 0, alpha: 0.2)
  182. }
  183. self.flag_ = false
  184. self.inputRespButton_.isHidden = false
  185. }
  186. }
  187. func controlTextDidChange(_ obj: Notification) {
  188. if self.inputTextF.isEqual(to: obj.object) {
  189. self.inputDidChanged?(self.inputTextF.stringValue, nil)
  190. }
  191. }
  192. func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
  193. switch commandSelector {
  194. case #selector(NSResponder.insertNewline(_:)):
  195. if let inputView = control as? NSTextField {
  196. if inputView == self.inputTextF {
  197. self.itemClick?(3, self.inputTextF.stringValue)
  198. }
  199. }
  200. return true
  201. default:
  202. return false
  203. }
  204. }
  205. }