KMNQuickToolWindowController.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. //
  2. // KMNQuickToolWindowController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by 丁林圭 on 2024/10/10.
  6. //
  7. import Cocoa
  8. import KMComponentLibrary
  9. //MARK: - KMNQuickToolWindowDelegate
  10. protocol KMNQuickToolWindowDelegate: AnyObject {
  11. func quickToolWindowControllerUpdate()
  12. }
  13. //MARK: - KMNQuickToolWindowController
  14. class KMNQuickToolWindowController: KMNBaseWindowController, NSCollectionViewDelegate, NSCollectionViewDataSource,NSCollectionViewDelegateFlowLayout {
  15. weak open var delegate: KMNQuickToolWindowDelegate?
  16. @IBOutlet var viewBackBox: NSBox!
  17. @IBOutlet var titleLabel: NSTextField!
  18. @IBOutlet var titleBox: NSBox!
  19. @IBOutlet var titleSubLabel: NSTextField!
  20. @IBOutlet var showBox: NSBox!
  21. @IBOutlet var showCollectionView: NSCollectionView!
  22. @IBOutlet var cancelButton: ComponentButton!
  23. @IBOutlet var applyButton: ComponentButton!
  24. @IBOutlet var cancelWidthButton:NSLayoutConstraint!
  25. @IBOutlet var applyWidthButton:NSLayoutConstraint!
  26. var quickToolsItemMutableArray: [Int] = []
  27. var draggedItemIndexPath: IndexPath?
  28. var changeIndexPaths: Set<IndexPath> = []
  29. lazy var showDates: [KMNHomeQuickToolMode] = {
  30. var fullDatas: [KMNHomeQuickToolMode] = []
  31. for itemRaw in KMNHomeQuickToolManager.defaultManager.fullToolsItemMutableArray {
  32. let toolMode = KMNHomeQuickToolMode.toolModeData(type: HomeQuickToolType(rawValue: itemRaw) ?? .Batch)
  33. fullDatas.append(toolMode)
  34. }
  35. return fullDatas
  36. }()
  37. override func windowDidLoad() {
  38. super.windowDidLoad()
  39. quickToolsItemMutableArray = KMNHomeQuickToolManager.defaultManager.quickToolsItemMutableArray
  40. updateButtonState()
  41. showCollectionView.delegate = self
  42. showCollectionView.dataSource = self
  43. showCollectionView.isSelectable = true //支持拖拽需设置未True
  44. showCollectionView.register(KMNQuickToolCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMNQuickToolShowCollectionViewItem"))
  45. showCollectionView.registerForDraggedTypes([.string])
  46. showCollectionView.setDraggingSourceOperationMask(.every, forLocal: false)
  47. showCollectionView.setDraggingSourceOperationMask(.every, forLocal: true)
  48. }
  49. func reloadData() {
  50. showCollectionView.reloadData()
  51. }
  52. override func initContentView() {
  53. titleLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-m-medium")
  54. titleSubLabel.font = ComponentLibrary.shared.getFontFromKey ("mac/body-xs-regular")
  55. applyButton.properties = ComponentButtonProperty(type: .primary,
  56. size: .s,
  57. state: .normal,
  58. buttonText: KMLocalizedString("Apply"))
  59. applyButton.setTarget(self, action: #selector(applyButtonClicked(_ :)))
  60. cancelButton.properties = ComponentButtonProperty(type: .default_tertiary,
  61. size: .s,
  62. state: .normal,
  63. buttonText: KMLocalizedString("Cancel"))
  64. cancelButton.setTarget(self, action: #selector(cancelButtonClicked(_ :)))
  65. }
  66. override func updateUIThemeColor() {
  67. window?.contentView?.wantsLayer = true
  68. window?.contentView?.layer?.backgroundColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/popUp").cgColor
  69. titleLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/1")
  70. titleBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorFill/3-default")
  71. titleBox.borderColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/3-default")
  72. titleSubLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2")
  73. cancelButton.reloadData()
  74. applyButton.reloadData()
  75. }
  76. override func updateUILanguage() {
  77. titleSubLabel.stringValue = KMLocalizedString("Select a maximum of 8 tools. You can drag and drop to reorder the tools display.")
  78. titleLabel.stringValue = KMLocalizedString("Manage Quick Tools")
  79. showCollectionView.reloadData()
  80. cancelButton.properties.buttonText = KMLocalizedString("Cancel")
  81. applyButton.properties.buttonText = KMLocalizedString("Apply")
  82. cancelWidthButton.constant = cancelButton.properties.propertyInfo.viewWidth
  83. applyWidthButton.constant = applyButton.properties.propertyInfo.viewWidth
  84. }
  85. private func updateButtonState() {
  86. if self.quickToolsItemMutableArray.count < 1 {
  87. if applyButton.properties.isDisabled == false {
  88. applyButton.properties.isDisabled = true
  89. applyButton.reloadData()
  90. }
  91. } else {
  92. if applyButton.properties.isDisabled == true {
  93. applyButton.properties.isDisabled = false
  94. applyButton.reloadData()
  95. }
  96. }
  97. }
  98. private func updateCellOpacity(at location: NSPoint, opacity: CGFloat) {
  99. let pointInCollectionView = showCollectionView.convert(location, from: nil)
  100. if let indexPath = showCollectionView.indexPathForItem(at: pointInCollectionView) {
  101. if let item = showCollectionView.item(at: indexPath) as? KMNQuickToolCollectionViewItem {
  102. item.view.alphaValue = opacity
  103. }
  104. }
  105. }
  106. private func resetCellOpacity() {
  107. for item in showCollectionView.visibleItems() {
  108. item.view.alphaValue = 1.0
  109. }
  110. }
  111. //MARK: - Action
  112. @objc func cancelButtonClicked(_ sender: NSView) {
  113. own_closeEndSheet()
  114. }
  115. @objc func applyButtonClicked(_ sender: NSView) {
  116. var seleteDatas:[Int] = []
  117. var fullDatas:[Int] = []
  118. for i in 0 ... showDates.count-1 {
  119. let indexPath = NSIndexPath(forItem: i, inSection: 0)
  120. if let cell = showCollectionView.item(at: indexPath as IndexPath) as? KMNQuickToolCollectionViewItem {
  121. if cell.itemCardView.properties.isSelected == true {
  122. seleteDatas.append(cell.quickToolModel.quickToolType.rawValue)
  123. }
  124. fullDatas.append(cell.quickToolModel.quickToolType.rawValue)
  125. }
  126. }
  127. KMNHomeQuickToolManager.defaultManager.quickToolsItemMutableArray = seleteDatas
  128. KMNHomeQuickToolManager.defaultManager.fullToolsItemMutableArray = fullDatas
  129. self.delegate?.quickToolWindowControllerUpdate()
  130. own_closeEndSheet()
  131. }
  132. //MARK: - NSCollectionViewDataSource
  133. func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
  134. return showDates.count
  135. }
  136. func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
  137. let item: KMNQuickToolCollectionViewItem = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMNQuickToolShowCollectionViewItem"), for: indexPath) as! KMNQuickToolCollectionViewItem
  138. item.quickToolModel = showDates[indexPath.item]
  139. item.isNewState = item.quickToolModel.isNewState
  140. if(quickToolsItemMutableArray.contains(item.quickToolModel.quickToolType.rawValue)) {
  141. item.isShowState = true
  142. } else {
  143. item.isShowState = false
  144. }
  145. item.clickCallBack = {[weak self] isSelecton in
  146. guard let weakSelf = self else { return }
  147. if(isSelecton) {
  148. if(weakSelf.quickToolsItemMutableArray.count < 8) {
  149. weakSelf.quickToolsItemMutableArray.append(item.quickToolModel.quickToolType.rawValue)
  150. } else {
  151. item.isShowState = false
  152. let contextString = KMLocalizedString("You can select up to 8 tools. Please cancel and select.")
  153. let superView = weakSelf.window?.contentView ?? NSView()
  154. _ = KMNCustomAlertView.alertView(message: contextString, type: .normal_custom, fromView: superView, point:CGPointMake(superView.frame.origin.x + superView.frame.size.width/2, superView.frame.origin.y + superView.frame.size.height/2))
  155. }
  156. } else {
  157. weakSelf.quickToolsItemMutableArray.removeObject(item.quickToolModel.quickToolType.rawValue)
  158. }
  159. weakSelf.updateButtonState()
  160. }
  161. return item
  162. }
  163. // MARK: - NSCollectionViewDelegateFlowLayout
  164. func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
  165. return CGSize(width: 204.0, height: 56.0)
  166. }
  167. func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
  168. return 4
  169. }
  170. func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
  171. return 4
  172. }
  173. public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, insetForSectionAt section: Int) -> NSEdgeInsets {
  174. return NSEdgeInsetsMake(0, 8, 0, 0)
  175. }
  176. //MARK: - NSCollectionViewDelegate
  177. func collectionView(_ collectionView: NSCollectionView, canDragItemsAt indexPaths: Set<IndexPath>, with event: NSEvent) -> Bool {
  178. return true
  179. }
  180. func collectionView(_ collectionView: NSCollectionView, pasteboardWriterForItemAt indexPath: IndexPath) -> NSPasteboardWriting? {
  181. return String(indexPath.item) as NSPasteboardWriting
  182. }
  183. func collectionView(_ collectionView: NSCollectionView, validateDrop draggingInfo: NSDraggingInfo, proposedIndexPath proposedDropIndexPath: AutoreleasingUnsafeMutablePointer<NSIndexPath>, dropOperation proposedDropOperation: UnsafeMutablePointer<NSCollectionView.DropOperation>) -> NSDragOperation {
  184. resetCellOpacity()
  185. updateCellOpacity(at: draggingInfo.draggingLocation, opacity: 0.5)
  186. return .move
  187. }
  188. func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItemsAt indexPaths: Set<IndexPath>) {
  189. draggedItemIndexPath = indexPaths.first
  190. }
  191. func collectionView(_ collectionView: NSCollectionView, acceptDrop draggingInfo: NSDraggingInfo, indexPath: IndexPath, dropOperation: NSCollectionView.DropOperation) -> Bool {
  192. let result = false
  193. let toItemIndex = indexPath.item
  194. guard let fromItemIndex = draggedItemIndexPath?.item else {
  195. return result
  196. }
  197. // 确保索引有效
  198. if fromItemIndex < 0 || fromItemIndex >= showDates.count || toItemIndex < 0 || toItemIndex > showDates.count {
  199. return result // 无效索引
  200. }
  201. var indexPaths: Set<IndexPath> = []
  202. if dropOperation == .before {
  203. let num = showDates[fromItemIndex]
  204. showDates.insert(num, at: toItemIndex)
  205. if toItemIndex > fromItemIndex { // 向后移动
  206. showDates.remove(at: fromItemIndex)
  207. } else {
  208. showDates.remove(at: fromItemIndex + 1)
  209. }
  210. for i in min(fromItemIndex, toItemIndex)..<(max(fromItemIndex, toItemIndex)+1) {
  211. indexPaths.insert(IndexPath(item: i, section: 0))
  212. }
  213. showCollectionView.reloadItems(at: indexPaths)
  214. } else {
  215. let fromIndexPath = IndexPath(item: fromItemIndex, section: 0)
  216. indexPaths = [indexPath, fromIndexPath]
  217. showDates.swapAt(fromItemIndex, toItemIndex)
  218. showCollectionView.reloadItems(at: indexPaths)
  219. }
  220. changeIndexPaths = [indexPath]
  221. return true
  222. }
  223. func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, dragOperation operation: NSDragOperation) {
  224. for targetIndexPath in changeIndexPaths {
  225. let targetItem = collectionView.item(at: targetIndexPath)
  226. targetItem?.view.shakeAnimation()
  227. }
  228. changeIndexPaths = []
  229. resetCellOpacity()
  230. }
  231. }