SKPresentationOptionsSheetController.swift 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. //
  2. // SKPresentationOptionsSheetController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by liujiajie on 2024/1/17.
  6. //
  7. import Cocoa
  8. typealias closePresentationControllerCallBack = (_ vc: SKPresentationOptionsSheetController) -> ()
  9. let RIGHTARROW_CHARACTER: unichar = 0x2192
  10. let PAGE_COLUMNID = "page"
  11. let IMAGE_COLUMNID = "image"
  12. let TRANSITIONSTYLE_KEY = "transitionStyle"
  13. let DURATION_KEY = "duration"
  14. let SHOULDRESTRICT_KEY = "shouldRestrict"
  15. let PROPERTIES_KEY = "properties"
  16. let CONTENTOBJECT_BINDINGNAME = "contentObject"
  17. let MAX_PAGE_COLUMN_WIDTH: CGFloat = 100.0
  18. let TABLE_OFFSET: CGFloat = 8.0
  19. //var SKTransitionPropertiesObservationContext = UnsafeMutableRawPointer(mutating: "SKTransitionPropertiesObservationContext")
  20. var SKPDFViewTransitionsObservationContext: CChar?
  21. class SKPresentationOptionsSheetController: KMBaseWindowController {
  22. @IBOutlet var notesDocumentPopUpButton: NSPopUpButton!
  23. @IBOutlet var tableView: KMBotaTableView!
  24. @IBOutlet var separateCheckButton: NSButton!
  25. @IBOutlet var boxes, transitionLabels, transitionControls, buttons: NSArray!
  26. @IBOutlet var effectPopUpButton: NSPopUpButton!
  27. @IBOutlet var effectLabel: NSTextField!
  28. @IBOutlet var durationLabel: NSTextField!
  29. @IBOutlet var durationSlider: NSSlider!
  30. @IBOutlet var durationTF: NSTextField!
  31. @IBOutlet var extentLabel: NSTextField!
  32. @IBOutlet var screeBtn: NSButtonCell!
  33. @IBOutlet var pageBtn: NSButtonCell!
  34. @IBOutlet var synchoronizBox: NSBox!
  35. @IBOutlet var cancelBtn: NSButton!
  36. @IBOutlet var okBtn: NSButton!
  37. @IBOutlet var pageTransitionBox: NSBox!
  38. var closeCallBack: closePresentationControllerCallBack?
  39. var separate = false
  40. var transition: KMTransitionInfo = KMTransitionInfo()
  41. private var transitions_: NSArray?
  42. var transitions: NSArray? {
  43. get {
  44. return self.transitions_
  45. }
  46. set{
  47. if self.transitions_ != newValue {
  48. // (undoRedoManager?.prepare(withInvocationTarget: self) as AnyObject).transitions = transitions
  49. self.transitions_ = newValue
  50. stopObservingTransitions(infos: transitions as! [KMTransitionInfo])
  51. startObservingTransitions(transitions as! [KMTransitionInfo])
  52. }
  53. }
  54. }
  55. var currentTransitions: NSArray? {
  56. get{
  57. return self.separate ? self.transitions : [transition as Any]
  58. }
  59. }
  60. var pageTransitions: NSArray? {
  61. get{
  62. if self.separate && self.transitions?.count ?? 0 > 0 {
  63. return [transitions?.value(forKey: PROPERTIES_KEY) as Any]
  64. }
  65. return nil
  66. }
  67. }
  68. var notesDocument: NSDocument? {
  69. get{
  70. _ = self.window
  71. return self.notesDocumentPopUpButton.selectedItem?.representedObject as? NSDocument
  72. }
  73. }
  74. var isScrolling: Bool {
  75. get{
  76. let scroller = self.tableView?.enclosingScrollView?.verticalScroller as? KMScroller
  77. return scroller?.isScrolling ?? false
  78. }
  79. }
  80. var undoRedoManager = UndoManager()
  81. weak var controller: KMMainViewController?
  82. weak var transitionController: SKTransitionController?
  83. private weak var proxyDelegate_: SKTransitionControllerDelegate?
  84. // class func keyPathsForValuesAffectingCurrentTransitions() -> Set<String> {
  85. // return Set<String>(["separate", "transitions", "transition"])
  86. // }
  87. override var windowNibName: NSNib.Name?{
  88. return "TransitionSheet"
  89. }
  90. override init(window: NSWindow?) {
  91. super.init(window: window)
  92. }
  93. required init?(coder: NSCoder) {
  94. super.init(coder: coder)
  95. }
  96. override func windowDidLoad() {
  97. super.windowDidLoad()
  98. let count = SKTransitionController.transitionNames().count
  99. for i in 0..<count {
  100. self.effectPopUpButton.addItem(withTitle: SKTransitionController.localizedName(for: SKAnimationTransitionStyle(rawValue: UInt(i)) ?? .noTransition))
  101. self.effectPopUpButton.lastItem?.tag = i
  102. }
  103. self.notesDocumentPopUpButton.item(at: 0)?.title = NSLocalizedString("None", comment: "Menu item title")
  104. // creatTransitionController()
  105. let transitionController = self.controller?.listView.transitionController
  106. self.proxyDelegate_ = transitionController?.delegate
  107. transitionController?.delegate = self
  108. self.transitionController = transitionController
  109. self.transition.transitionStyle = transitionController?.transitionStyle ?? .noTransition
  110. self.transition.duration = Float(transitionController?.duration ?? 0)
  111. self.transition.shouldRestrict = transitionController?.shouldRestrict ?? false
  112. self.startObservingTransitions([self.transition])
  113. self.separateCheckButton.sizeToFit()
  114. SKAutoSizeButtons(buttons as? [Any], true)
  115. let dw = SKAutoSizeLabelFields(transitionLabels as? [Any], transitionControls as? [Any], false)
  116. if abs(dw) > 0.0 {
  117. SKResizeWindow(self.window, dw)
  118. SKShiftAndResizeViews(self.boxes as? [Any], -dw, dw)
  119. SKShiftAndResizeView(self.separateCheckButton, -dw, 0.0)
  120. }
  121. // collapse the table
  122. self.window?.setFrame(NSInsetRect(window?.frame ?? .zero, 0.5 * (NSWidth(tableView.enclosingScrollView!.frame) + TABLE_OFFSET), 0.0), display: false)
  123. self.tableView.registerForDraggedTypes(KMTransitionInfo.readableTypesForPasteboard(pasteboard: NSPasteboard(name: NSPasteboard.Name.drag)) as! [NSPasteboard.PasteboardType])
  124. self.tableView.delegate = self
  125. self.tableView.dataSource = self
  126. self.tableView.botaDelegate = self
  127. self.tableView.setTypeSelectHelper(SKTypeSelectHelper(matchOption: .SKFullStringMatch))
  128. self.tableView.hasImageToolTips = true
  129. self.tableView.backgroundColor = NSColor.mainSourceListBackgroundColor()
  130. if (transitionController?.pageTransitions != nil && transitionController?.pageTransitions.count ?? 0 > 0) {
  131. self.undoRedoManager.disableUndoRegistration()
  132. self.separate = true
  133. self.undoRedoManager.enableUndoRegistration()
  134. }
  135. // set the current notes document and observe changes for the popup
  136. self.handleDocumentsDidChangeNotification(notification: nil)
  137. let docIndex = self.notesDocumentPopUpButton.indexOfItem(withRepresentedObject: self.controller?.myDocument/*presentationNotesDocument*/)
  138. self.notesDocumentPopUpButton.selectItem(at: docIndex > 0 ? docIndex : 0)
  139. NotificationCenter.default.addObserver(self, selector: #selector(handleDocumentsDidChangeNotification(notification:)), name: NSNotification.Name("SKDocumentDidShowNotification"), object: nil)
  140. NotificationCenter.default.addObserver(self, selector: #selector(handleDocumentsDidChangeNotification(notification:)), name: NSNotification.Name("SKDocumentControllerDidRemoveDocumentNotification"), object: nil)
  141. }
  142. override func initDefaultValue() {
  143. super.initDefaultValue()
  144. self.effectPopUpButton.target = self
  145. self.effectPopUpButton.action = #selector(effectButtonAction)
  146. self.durationTF.formatter = NumberFormatter()
  147. self.durationTF.delegate = self
  148. self.screeBtn.target = self
  149. self.screeBtn.action = #selector(extentAction)
  150. self.pageBtn.target = self
  151. self.pageBtn.action = #selector(extentAction)
  152. }
  153. func stopObservingTransitions(infos: [KMTransitionInfo]) {
  154. // for info in infos {
  155. // info.removeObserver(self, forKeyPath: TRANSITIONSTYLE_KEY)
  156. // info.removeObserver(self, forKeyPath: DURATION_KEY)
  157. // info.removeObserver(self, forKeyPath: SHOULDRESTRICT_KEY)
  158. // }
  159. }
  160. // func creatTransitionController() {
  161. // transitionController = SKTransitionController(for: controller?.listView)//controller?.mainViewController.listView.transitionController
  162. // let options: NSKeyValueObservingOptions = [.new, .old]
  163. // transitionController?.addObserver(self, forKeyPath: "transitionStyle", options: options, context: &SKPDFViewTransitionsObservationContext)
  164. // transitionController?.addObserver(self, forKeyPath: "duration", options: options, context: &SKPDFViewTransitionsObservationContext)
  165. // transitionController?.addObserver(self, forKeyPath: "shouldRestrict", options: options, context: &SKPDFViewTransitionsObservationContext)
  166. // transitionController?.addObserver(self, forKeyPath: "pageTransitions", options: options, context: &SKPDFViewTransitionsObservationContext)
  167. // }
  168. func startObservingTransitions(_ infos: [KMTransitionInfo]) {
  169. // for info in infos {
  170. // info.addObserver(self, forKeyPath: TRANSITIONSTYLE_KEY, options: [.new, .old], context: &SKTransitionPropertiesObservationContext)
  171. // info.addObserver(self, forKeyPath: DURATION_KEY, options: [.new, .old], context: &SKTransitionPropertiesObservationContext)
  172. // info.addObserver(self, forKeyPath: SHOULDRESTRICT_KEY, options: [.new, .old], context: &SKTransitionPropertiesObservationContext)
  173. // }
  174. }
  175. func setValue(_ value: Any?, forKey key: String, ofTransition info: KMTransitionInfo) {
  176. info.setValue(value, forKey: key)
  177. }
  178. // override class func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
  179. // if context == &SKTransitionPropertiesObservationContext {
  180. // guard let info = object as? KMTransitionInfo else {
  181. // super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
  182. // return
  183. // }
  184. // let newValue = change?[.newKey]
  185. // let oldValue = change?[.oldKey]
  186. //
  187. // let newNonNullValue = newValue as? NSNull == nil ? newValue : nil
  188. // let oldNonNullValue = oldValue as? NSNull == nil ? oldValue : nil
  189. //
  190. //// if (newNonNullValue != nil || oldNonNullValue != nil) && newNonNullValue != oldNonNullValue {
  191. //// (undoManager?.prepare(withInvocationTarget: self) as AnyObject).setValue(oldNonNullValue, forKey: keyPath, ofTransition: info)
  192. //// }
  193. // if (newNonNullValue != nil || oldNonNullValue != nil){
  194. //
  195. // }
  196. // } else {
  197. // super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
  198. // }
  199. // }
  200. // MARK: - Private
  201. private func makeTransitions() {
  202. if transitions != nil {
  203. return
  204. }
  205. let tableColumn = self.tableView?.tableColumn(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: PAGE_COLUMNID))
  206. let cell = tableColumn?.dataCell
  207. var labelWidth: CGFloat = 0.0
  208. var array = [Any]()
  209. let dictionary: NSDictionary? = self.transition.properties
  210. let arr: NSArray? = self.transitionController?.pageTransitions as NSArray?
  211. let ptEnum = arr?.objectEnumerator()
  212. var tn: KMThumbnail? = nil
  213. for next in (controller?.leftSideViewController.thumbnails)! {
  214. if tn != nil {
  215. let info = KMTransitionInfo()
  216. info.thumbnail = tn
  217. info.label = "\(tn!.label)"+"→"+"\(next.label)"
  218. info.properties = ((ptEnum?.nextObject()) != nil) ? ptEnum?.nextObject() as? NSDictionary : dictionary
  219. array.append(info)
  220. (cell as AnyObject).setStringValue(info.label)
  221. labelWidth = max(labelWidth, ceil(((cell as AnyObject).cellSize?.width)!))
  222. }
  223. tn = next
  224. }
  225. labelWidth = min(labelWidth, MAX_PAGE_COLUMN_WIDTH)
  226. tableColumn?.minWidth = labelWidth
  227. tableColumn?.maxWidth = labelWidth
  228. tableColumn?.width = labelWidth
  229. var frame: NSRect = self.tableView?.enclosingScrollView?.frame ?? .zero
  230. let wi: CGFloat = 61//tableColumn?.value(forKeyPath: "@sum.width") as! CGFloat
  231. frame.size.width = 19.0 + wi
  232. self.tableView?.enclosingScrollView?.frame = frame
  233. self.transitions = array as NSArray
  234. }
  235. @objc dynamic func changePageTransitionType(sep: Bool) {
  236. // SKImageToolTipWindow.sharedToolTipWindow().orderOut(nil)
  237. self.separate = sep
  238. self.separateCheckButton.state = sep ? .on : .off
  239. let window = self.window
  240. let isVisible = window?.isVisible ?? false
  241. var frame = window?.frame ?? NSRect.zero
  242. let scrollView = tableView?.enclosingScrollView
  243. var extraWidth: CGFloat
  244. let firstResponder = window?.firstResponder
  245. var editor: NSTextView? = nil
  246. if let textView = firstResponder as? NSTextView {
  247. editor = textView
  248. if textView.isFieldEditor {
  249. // firstResponder = textView.delegate
  250. }
  251. }
  252. if let editor = editor, window?.firstResponder != editor {
  253. window?.makeFirstResponder(firstResponder)
  254. }
  255. if sep {
  256. makeTransitions()
  257. extraWidth = (scrollView?.frame.width ?? 0) + TABLE_OFFSET
  258. frame.size.width += extraWidth
  259. frame.origin.x -= floor(0.5 * extraWidth)
  260. window?.setFrame(frame, display: isVisible, animate: isVisible)
  261. scrollView?.isHidden = false
  262. } else {
  263. scrollView?.isHidden = true
  264. extraWidth = (scrollView?.frame.width ?? 0) + TABLE_OFFSET
  265. frame.size.width -= extraWidth
  266. frame.origin.x += floor(0.5 * extraWidth)
  267. window?.setFrame(frame, display: isVisible, animate: isVisible)
  268. }
  269. (self.undoRedoManager.prepare(withInvocationTarget: self) as AnyObject).changePageTransitionType(sep: sep == false)
  270. }
  271. func selectedInfos() -> [KMTransitionInfo]? {
  272. if self.separate == false {
  273. return [self.transition]
  274. } else {
  275. guard let trans = self.transitions else {
  276. return nil
  277. }
  278. let ris = self.tableView.selectedRowIndexes
  279. var infos: [KMTransitionInfo] = []
  280. for ri in ris {
  281. if ri >= trans.count {
  282. continue
  283. }
  284. if let info = trans.object(at: ri) as? KMTransitionInfo {
  285. infos.append(info)
  286. }
  287. }
  288. return infos
  289. }
  290. }
  291. private func _updateInfo(key: String, value: Any) {
  292. if key == KMTransitionStyleName {
  293. let _value = value as? SKAnimationTransitionStyle ?? .noTransition
  294. if self.separate == false {
  295. self.transition.transitionStyle = _value
  296. } else {
  297. guard let trans = self.transitions else {
  298. return
  299. }
  300. let ris = self.tableView.selectedRowIndexes
  301. for ri in ris {
  302. if ri >= trans.count {
  303. continue
  304. }
  305. let info = trans.object(at: ri) as? KMTransitionInfo
  306. info?.transitionStyle = _value
  307. }
  308. }
  309. } else if key == KMDurationName {
  310. let _value = value as? Float ?? 0
  311. if self.separate == false {
  312. self.transition.duration = _value
  313. } else {
  314. guard let trans = self.transitions else {
  315. return
  316. }
  317. let ris = self.tableView.selectedRowIndexes
  318. for ri in ris {
  319. if ri >= trans.count {
  320. continue
  321. }
  322. let info = trans.object(at: ri) as? KMTransitionInfo
  323. info?.duration = _value
  324. }
  325. }
  326. } else if key == KMShouldRestrictName {
  327. let _value = value as? Bool ?? false
  328. if self.separate == false {
  329. self.transition.shouldRestrict = _value
  330. } else {
  331. guard let trans = self.transitions else {
  332. return
  333. }
  334. let ris = self.tableView.selectedRowIndexes
  335. for ri in ris {
  336. if ri >= trans.count {
  337. continue
  338. }
  339. let info = trans.object(at: ri) as? KMTransitionInfo
  340. info?.shouldRestrict = _value
  341. }
  342. }
  343. }
  344. }
  345. // Actions
  346. @objc func effectButtonAction(sender: NSPopUpButton) {
  347. let index = sender.indexOfSelectedItem
  348. let names = SKTransitionController.transitionNames() as? [String]
  349. let name = names?.safe_element(for: index) as? String ?? ""
  350. let type = SKTransitionController.style(forName: name)
  351. guard let infos = self.selectedInfos(), infos.isEmpty == false else {
  352. NSSound.beep()
  353. return
  354. }
  355. for info in infos {
  356. if info.transitionStyle != type { // undo
  357. // let oldValue = info.transitionStyle
  358. self.undo_effectAction(info: info, key: KMTransitionStyleName, value: type, popup: nil)
  359. }
  360. }
  361. // self._updateInfo(key: KMTransitionStyleName, value: type)
  362. }
  363. @objc dynamic func undo_effectAction(info: KMTransitionInfo, key: String, value: Any, popup: NSPopUpButton?) {
  364. if key == KMTransitionStyleName {
  365. let oldValue = info.transitionStyle
  366. (self.undoRedoManager.prepare(withInvocationTarget: self) as AnyObject).undo_effectAction(info: info, key: key, value: oldValue, popup: self.effectPopUpButton)
  367. info.transitionStyle = value as? SKAnimationTransitionStyle ?? .noTransition
  368. popup?.selectItem(at: Int(info.transitionStyle.rawValue))
  369. }
  370. }
  371. @objc func extentAction(sender: NSMatrix) {
  372. // let isScreen = sender.isEqual(to: self.screeBtn)
  373. // self.screeBtn.state = isScreen ? .on : .off
  374. // self.pageBtn.state = isScreen ? .off : .on
  375. // let value = self.pageBtn. == .on
  376. let value = sender.selectedTag() == 1 ? true : false
  377. // (self.undoRedoManager.prepare(withInvocationTarget: self) as AnyObject).extentAction(sender: sender)
  378. self.undoRedoManager.registerUndo(withTarget: self) { target in
  379. if value {
  380. target.screeBtn.performClick(nil)
  381. } else {
  382. target.pageBtn.performClick(nil)
  383. }
  384. }
  385. self._updateInfo(key: KMShouldRestrictName, value: value)
  386. }
  387. @IBAction func pageTransitionAction(_ sender: NSButton) {
  388. self.separate = sender.state == .on
  389. self.changePageTransitionType(sep: self.separate)
  390. Task { @MainActor in
  391. self.tableView.reloadData()
  392. }
  393. }
  394. @IBAction func changeDurationSlider(_ sender: NSSlider) {
  395. // self.durationTF.stringValue = sender.stringValue
  396. guard let infos = self.selectedInfos(), infos.isEmpty == false else {
  397. NSSound.beep()
  398. return
  399. }
  400. for info in infos {
  401. if info.duration != sender.floatValue { // undo
  402. self.undo_sliderAction(info: info, key: KMDurationName, value: sender.floatValue, slider: nil, textF: self.durationTF)
  403. }
  404. }
  405. // 更新数据
  406. // self._updateInfo(key: KMDurationName, value: sender.floatValue)
  407. }
  408. @objc func undo_sliderAction(info: KMTransitionInfo, key: String, value: Any, slider: NSSlider?, textF: NSTextField?) {
  409. if key == KMDurationName {
  410. let oldValue = info.duration
  411. (self.undoRedoManager.prepare(withInvocationTarget: self) as AnyObject).undo_sliderAction(info: info, key: key, value: oldValue, slider: self.durationSlider, textF: self.durationTF)
  412. let duration = value as? Float ?? 0
  413. slider?.floatValue = duration
  414. textF?.floatValue = duration
  415. }
  416. }
  417. @IBAction func cancelAction(_ sender: Any) {
  418. if let handle = self.closeCallBack {
  419. handle(self)
  420. }
  421. }
  422. @IBAction func okAction(_ sender: Any) {
  423. if let handle = self.closeCallBack {
  424. handle(self)
  425. }
  426. if self.undoRedoManager.canUndo {
  427. self.transitionController?.transitionStyle = transition.transitionStyle
  428. self.transitionController?.duration = CGFloat(transition.duration)
  429. self.transitionController?.shouldRestrict = transition.shouldRestrict
  430. self.transitionController?.pageTransitions = pageTransitions as? [Any]
  431. (self.controller?.undoManager)?.setActionName(NSLocalizedString("Change Transitions", comment: "Undo action name"))
  432. }
  433. // self.controller?.myDocument/*presentationNotesDocument*/ = notesDocument
  434. }
  435. // Noti Actions
  436. @objc private func handleDocumentsDidChangeNotification(notification: Notification?) {
  437. let currentDoc = self.notesDocumentPopUpButton.selectedItem?.representedObject as? NSDocument
  438. while self.notesDocumentPopUpButton.numberOfItems > 1 {
  439. self.notesDocumentPopUpButton.removeItem(at: self.notesDocumentPopUpButton.numberOfItems - 1)
  440. }
  441. // var doc: NSDocument?
  442. let document = self.controller?.myDocument
  443. let documents = NSMutableArray()
  444. let pageCount = self.controller?.document?.pageCount ?? 0
  445. for doc in NSDocumentController.shared.documents {
  446. guard let mainDoc = doc as? KMMainDocument else {
  447. continue
  448. }
  449. if mainDoc.isHome {
  450. continue
  451. }
  452. if mainDoc.isEqual(to: document) {
  453. continue
  454. }
  455. if let pdfDoc = mainDoc.mainViewController?.document {
  456. if pdfDoc.pageCount == pageCount {
  457. documents.add(doc)
  458. }
  459. }
  460. }
  461. let sortDescriptor = NSSortDescriptor(key: "displayName", ascending: true)
  462. documents.sort(using: [sortDescriptor])
  463. for doc in documents {
  464. self.notesDocumentPopUpButton.addItem(withTitle: (doc as AnyObject).displayName)
  465. self.notesDocumentPopUpButton.lastItem?.representedObject = doc
  466. }
  467. let docIndex = self.notesDocumentPopUpButton.indexOfItem(withRepresentedObject: currentDoc)
  468. self.notesDocumentPopUpButton.selectItem(at: docIndex == -1 ? 0 : docIndex)
  469. }
  470. }
  471. // MARK: - NSTextFieldDelegate
  472. extension SKPresentationOptionsSheetController: NSTextFieldDelegate {
  473. func controlTextDidChange(_ obj: Notification) {
  474. if self.durationTF.isEqual(to: obj.object) {
  475. self.durationSlider.floatValue = self.durationTF.floatValue
  476. // 更新数据
  477. self._updateInfo(key: KMDurationName, value: self.durationTF.floatValue)
  478. }
  479. }
  480. }
  481. // MARK: - NSWindowDelegate
  482. extension SKPresentationOptionsSheetController: NSWindowDelegate {
  483. func windowWillReturnUndoManager(_ window: NSWindow) -> UndoManager? {
  484. return self.undoRedoManager
  485. }
  486. }
  487. // MARK: - SKTransitionControllerDelegate
  488. extension SKPresentationOptionsSheetController: SKTransitionControllerDelegate {
  489. func transitionController(_ controller: SKTransitionController!, valueDidChanged info: [AnyHashable : Any]!) {
  490. // 消息转发
  491. self.proxyDelegate_?.transitionController(controller, valueDidChanged: info)
  492. }
  493. }
  494. // MARK: - NSTableViewDelegate, NSTableViewDataSource
  495. extension SKPresentationOptionsSheetController: NSTableViewDelegate, NSTableViewDataSource {
  496. func numberOfRows(in tableView: NSTableView) -> Int {
  497. return self.transitions?.count ?? 0
  498. }
  499. func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
  500. let identifier = tableColumn?.identifier
  501. let info = transitions?[row] as? KMTransitionInfo
  502. if let id = identifier?.rawValue, id == PAGE_COLUMNID {
  503. let cell = tableColumn?.dataCell as? NSTextFieldCell
  504. cell?.stringValue = info?.label ?? ""
  505. return info?.label ?? ""
  506. } else if let id = identifier?.rawValue, id == IMAGE_COLUMNID {
  507. let cell = tableColumn?.dataCell as? NSImageCell
  508. let page = self.controller?.listView.document.page(at: UInt(info?.thumbnail?.pageIndex ?? 0))
  509. if let data = page?.PDFListViewTIFFData(for: page?.bounds ?? .zero) {
  510. let image = NSImage(data: data)
  511. cell?.image = image
  512. return image
  513. }
  514. }
  515. return nil
  516. }
  517. func tableViewSelectionDidChange(_ notification: Notification) {
  518. if self.tableView.isEqual(to: notification.object) == false {
  519. return
  520. }
  521. let ris = self.tableView.selectedRowIndexes
  522. if ris.isEmpty {
  523. return
  524. }
  525. var info: KMTransitionInfo?
  526. if ris.count == 1 {
  527. info = self.transitions?[ris.first ?? 0] as? KMTransitionInfo
  528. self.pageTransitionBox.title = KMLocalizedString("Page Transition") + (info?.label ?? "")
  529. // self.effectPopUpButton.selectItem(at: Int(info?.transitionStyle.rawValue ?? 0))
  530. // let durationV = info?.duration ?? 0
  531. // self.durationSlider.animator().floatValue = durationV
  532. // self.durationTF.floatValue = durationV
  533. // let shouldRestrict = info?.shouldRestrict ?? false
  534. // if shouldRestrict { // 1
  535. // self.pageBtn.state = .on
  536. // self.screeBtn.state = .off
  537. // } else {
  538. // self.screeBtn.state = .on
  539. // self.pageBtn.state = .off
  540. // }
  541. } else {
  542. self.pageTransitionBox.title = KMLocalizedString("Page Transition")
  543. info = self.transition
  544. }
  545. self.effectPopUpButton.selectItem(at: Int(info?.transitionStyle.rawValue ?? 0))
  546. let durationV = info?.duration ?? 0
  547. self.durationSlider.animator().floatValue = durationV
  548. self.durationTF.floatValue = durationV
  549. let shouldRestrict = info?.shouldRestrict ?? false
  550. if shouldRestrict { // 1
  551. self.pageBtn.state = .on
  552. self.screeBtn.state = .off
  553. } else {
  554. self.screeBtn.state = .on
  555. self.pageBtn.state = .off
  556. }
  557. }
  558. func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
  559. if rowIndexes.count == 1 {
  560. pboard.clearContents()
  561. pboard.writeObjects([transitions?[rowIndexes.first ?? 0] as! NSPasteboardWriting])
  562. return true
  563. } else {
  564. return false
  565. }
  566. }
  567. func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
  568. if info.draggingPasteboard.canReadObject(forClasses: [KMTransitionInfo.self], options: [:]) {
  569. if dropOperation == .above {
  570. tableView.setDropRow(-1, dropOperation: .on)
  571. }
  572. return .every
  573. }
  574. return []
  575. }
  576. func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
  577. let pboard = info.draggingPasteboard
  578. if dropOperation == .on {
  579. guard let infos = pboard.readObjects(forClasses: [KMTransitionInfo.self], options: [:]) as? [KMTransitionInfo], infos.count > 0 else {
  580. return false
  581. }
  582. let propertie: NSDictionary? = infos[0].properties
  583. if row == -1 {
  584. transitions?.setValue(propertie, forKey: PROPERTIES_KEY)
  585. } else {
  586. let transit: KMTransitionInfo = transitions?[row] as! KMTransitionInfo
  587. transit.properties = propertie
  588. }
  589. return true
  590. }
  591. return false
  592. }
  593. }
  594. extension SKPresentationOptionsSheetController: KMBotaTableViewDelegate {
  595. func tableView(_ aTableView: NSTableView, imageContextForRow rowIndex: Int) -> AnyObject? {
  596. return controller?.document?.page(at: UInt(rowIndex))
  597. }
  598. func tableView(_ aTableView: NSTableView, copyRowsWithIndexes rowIndexes: IndexSet) {
  599. let pboard = NSPasteboard.general
  600. pboard.clearContents()
  601. pboard.writeObjects([transitions?[rowIndexes.first ?? 0] as! NSPasteboardWriting])
  602. }
  603. func tableView(_ aTableView: NSTableView, canCopyRowsWithIndexes rowIndexes: IndexSet) -> Bool {
  604. return true
  605. }
  606. func tableView(_ aTableView: NSTableView, pasteFromPasteboard pboard: NSPasteboard) {
  607. guard let infos = pboard.readObjects(forClasses: [KMTransitionInfo.self], options: [:]) as? [KMTransitionInfo], infos.count > 0 else { return }
  608. let arr = transitions?.objects(at: tableView.selectedRowIndexes) as? NSArray
  609. arr?.setValue(infos[0].properties, forKey: PROPERTIES_KEY)
  610. }
  611. func tableView(_ aTableView: NSTableView, canPasteFromPasteboard pboard: NSPasteboard) -> Bool {
  612. return (tableView.selectedRow != -1 && pboard.canReadObject(forClasses: [KMTransitionInfo.self], options: [:]))
  613. }
  614. func tableView(_ aTableView: NSTableView, typeSelectHelperSelectionStrings aTypeSelectHelper: SKTypeSelectHelper) -> NSArray {
  615. return transitions?.value(forKeyPath: "thumbnail.label") as! NSArray
  616. }
  617. }