123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- //
- // SKPresentationOptionsSheetController.swift
- // PDF Reader Pro
- //
- // Created by liujiajie on 2024/1/17.
- //
- import Cocoa
- typealias closePresentationControllerCallBack = (_ vc: SKPresentationOptionsSheetController) -> ()
- let RIGHTARROW_CHARACTER: unichar = 0x2192
- let PAGE_COLUMNID = "page"
- let IMAGE_COLUMNID = "image"
- let TRANSITIONSTYLE_KEY = "transitionStyle"
- let DURATION_KEY = "duration"
- let SHOULDRESTRICT_KEY = "shouldRestrict"
- let PROPERTIES_KEY = "properties"
- let CONTENTOBJECT_BINDINGNAME = "contentObject"
- let MAX_PAGE_COLUMN_WIDTH: CGFloat = 100.0
- let TABLE_OFFSET: CGFloat = 8.0
- var SKTransitionPropertiesObservationContext = UnsafeMutableRawPointer(mutating: "SKTransitionPropertiesObservationContext")
- var SKPDFViewTransitionsObservationContext: CChar?
- class SKPresentationOptionsSheetController: NSWindowController, NSWindowDelegate, KMBotaTableViewDelegate, NSTableViewDataSource, NSTableViewDelegate{
- @IBOutlet var notesDocumentPopUpButton: NSPopUpButton!
- @IBOutlet var tableView: KMBotaTableView!
- @IBOutlet var separateCheckButton: NSButton!
- @IBOutlet var boxes, transitionLabels, transitionControls, buttons: NSArray!
- // @IBOutlet var arrayController: NSArrayController!
- @IBOutlet var effectPopUpButton: NSPopUpButton!
- @IBOutlet var effectLabel: NSTextField!
- @IBOutlet var durationLabel: NSTextField!
- @IBOutlet var durationSlider: NSSlider!
- @IBOutlet var durationTF: NSTextField!
- @IBOutlet var extentLabel: NSTextField!
- @IBOutlet var screeBtn: NSButtonCell!
- @IBOutlet var pageBtn: NSButtonCell!
- @IBOutlet var synchoronizBox: NSBox!
- @IBOutlet var cancelBtn: NSButton!
- @IBOutlet var okBtn: NSButton!
- @IBOutlet var pageTransitionBox: NSBox!
-
- var closeCallBack: closePresentationControllerCallBack?
- var separate = false
- var transition: KMTransitionInfo = KMTransitionInfo()
- var transitions: NSArray?{
- willSet{
-
- }
- didSet{
- if transitions != oldValue {
- // (undoRedoManager?.prepare(withInvocationTarget: self) as AnyObject).transitions = transitions
- stopObservingTransitions(infos: transitions as! [KMTransitionInfo])
- startObservingTransitions(transitions as! [KMTransitionInfo])
- }
- }
- }
- var currentTransitions: NSArray?{
- get{
- return separate ? transitions : [transition as Any]
- }
- set{
-
- }
- }
- var pageTransitions: NSArray?{
- get{
- if separate && transitions?.count ?? 0 > 0 {
- return [transitions?.value(forKey: PROPERTIES_KEY) as Any]
- } else {
- return nil
- }
- }
- set{
-
- }
- }
- var notesDocument: NSDocument?{
- get{
- return notesDocumentPopUpButton.selectedItem?.representedObject as? NSDocument
- }
- set{
-
- }
- }
- var isScrolling: Bool{
- get{
- if let scroller = tableView?.enclosingScrollView?.verticalScroller as? KMScroller {
- return scroller.isScrolling
- }
- return false
- }
- set{
-
- }
- }
- var undoRedoManager = UndoManager()
- var controller: KMMainViewController?
- var transitionController: SKTransitionController!
-
- class func keyPathsForValuesAffectingCurrentTransitions() -> Set<String> {
- return Set<String>(["separate", "transitions", "transition"])
- }
-
- // convenience init(for aController: KMMainViewController) {
- // super.init(window: window)
- // controller = aController
- // separate = false
- // transition = KMTransitionInfo()
- // transitions = nil
- // }
- override init(window: NSWindow?) {
- super.init(window: window)
- }
-
- required init?(coder: NSCoder) {
- super.init(coder: coder)
- }
-
- @objc func handleDocumentsDidChangeNotification(notification: Notification?) {
- guard let currentDoc = notesDocumentPopUpButton.selectedItem?.representedObject else { return }
- while notesDocumentPopUpButton.numberOfItems > 1 {
- notesDocumentPopUpButton.removeItem(at: notesDocumentPopUpButton.numberOfItems - 1)
- }
- guard let document = controller?.document as? NSDocument,
- let pageCount = controller?.listView.document?.pageCount else { return }
- let documents = NSMutableArray()
- for doc in NSDocumentController.shared.documents {
- if let pdfDoc = doc as? CPDFDocument,
- doc != document,
- pdfDoc.pageCount == pageCount {
- documents.add(doc)
- }
- }
- let sortDescriptor = NSSortDescriptor(key: "displayName", ascending: true)
- documents.sort(using: [sortDescriptor])
- for doc in documents {
- notesDocumentPopUpButton.addItem(withTitle: (doc as AnyObject).displayName)
- notesDocumentPopUpButton.lastItem?.representedObject = doc
- }
- let docIndex = notesDocumentPopUpButton.indexOfItem(withRepresentedObject: currentDoc)
- notesDocumentPopUpButton.selectItem(at: docIndex == -1 ? 0 : docIndex)
- }
-
- func stopObservingTransitions(infos: [KMTransitionInfo]) {
- for info in infos {
- info.removeObserver(self, forKeyPath: TRANSITIONSTYLE_KEY)
- info.removeObserver(self, forKeyPath: DURATION_KEY)
- info.removeObserver(self, forKeyPath: SHOULDRESTRICT_KEY)
- }
- }
-
- func creatTransitionController() {
- transitionController = SKTransitionController(for: controller?.listView)//controller?.mainViewController.listView.transitionController
- let options: NSKeyValueObservingOptions = [.new, .old]
- transitionController?.addObserver(self, forKeyPath: "transitionStyle", options: options, context: &SKPDFViewTransitionsObservationContext)
- transitionController?.addObserver(self, forKeyPath: "duration", options: options, context: &SKPDFViewTransitionsObservationContext)
- transitionController?.addObserver(self, forKeyPath: "shouldRestrict", options: options, context: &SKPDFViewTransitionsObservationContext)
- transitionController?.addObserver(self, forKeyPath: "pageTransitions", options: options, context: &SKPDFViewTransitionsObservationContext)
- }
-
- override func windowDidLoad() {
- super.windowDidLoad()
-
- let count = SKTransitionController.transitionNames().count
- // let transitionStylePopUpButton = transitionControls[0] as! NSPopUpButton
- // transitionStylePopUpButton.removeAllItems()
- for i in 0..<count {
- effectPopUpButton.addItem(withTitle: SKTransitionController.localizedName(for: SKAnimationTransitionStyle(rawValue: UInt(i)) ?? .noTransition))
- effectPopUpButton.lastItem?.tag = i
- }
- notesDocumentPopUpButton.item(at: 0)?.title = NSLocalizedString("None", comment: "Menu item title")
- creatTransitionController()
- transition.transitionStyle = transitionController?.transitionStyle ?? .noTransition
- transition.duration = Float(transitionController?.duration ?? 0)
- transition.shouldRestrict = transitionController?.shouldRestrict ?? false
- startObservingTransitions([transition])
- separateCheckButton.sizeToFit()
- // transitionControls.lastObject.sizeToFit()
- SKAutoSizeButtons(buttons as? [Any], true)
- let dw = SKAutoSizeLabelFields(transitionLabels as? [Any], transitionControls as? [Any], false)
- if abs(dw) > 0.0 {
- SKResizeWindow(window, dw)
- SKShiftAndResizeViews(boxes as? [Any], -dw, dw)
- SKShiftAndResizeView(separateCheckButton, -dw, 0.0)
- }
- // collapse the table
- window?.setFrame(NSInsetRect(window?.frame ?? .zero, 0.5 * (NSWidth(tableView.enclosingScrollView!.frame) + TABLE_OFFSET), 0.0), display: false)
- tableView.registerForDraggedTypes(KMTransitionInfo.readableTypesForPasteboard(pasteboard: NSPasteboard(name: NSPasteboard.Name.drag)) as! [NSPasteboard.PasteboardType])
-
- tableView.delegate = self
- tableView.dataSource = self
- tableView.botaDelegate = self
- tableView.setTypeSelectHelper(SKTypeSelectHelper(matchOption: .SKFullStringMatch))
- tableView.hasImageToolTips = true
- tableView.backgroundColor = NSColor.mainSourceListBackgroundColor()
- if (transitionController?.pageTransitions != nil && transitionController?.pageTransitions.count ?? 0 > 0) {
- undoManager?.disableUndoRegistration()
- separate = true
- undoManager?.enableUndoRegistration()
- }
- // set the current notes document and observe changes for the popup
- handleDocumentsDidChangeNotification(notification: nil)
- let docIndex = notesDocumentPopUpButton.indexOfItem(withRepresentedObject: controller?.myDocument/*presentationNotesDocument*/)
- notesDocumentPopUpButton.selectItem(at: docIndex > 0 ? docIndex : 0)
-
- NotificationCenter.default.addObserver(self, selector: #selector(handleDocumentsDidChangeNotification(notification:)), name: NSNotification.Name("SKDocumentDidShowNotification"), object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(handleDocumentsDidChangeNotification(notification:)), name: NSNotification.Name("SKDocumentControllerDidRemoveDocumentNotification"), object: nil)
- }
-
- func startObservingTransitions(_ infos: [KMTransitionInfo]) {
- for info in infos {
- info.addObserver(self, forKeyPath: TRANSITIONSTYLE_KEY, options: [.new, .old], context: &SKTransitionPropertiesObservationContext)
- info.addObserver(self, forKeyPath: DURATION_KEY, options: [.new, .old], context: &SKTransitionPropertiesObservationContext)
- info.addObserver(self, forKeyPath: SHOULDRESTRICT_KEY, options: [.new, .old], context: &SKTransitionPropertiesObservationContext)
- }
- }
-
- func makeTransitions() {
- if transitions != nil { return }
- let tableColumn = tableView?.tableColumn(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: PAGE_COLUMNID))
- let cell = tableColumn?.dataCell
- var labelWidth: CGFloat = 0.0
-
- var array = [Any]()
- _ = transition.properties
- let arr: NSArray? = transitionController.pageTransitions as NSArray?
- let ptEnum = arr?.objectEnumerator()
- var tn: KMThumbnail? = nil
-
- for next in (controller?.leftSideViewController.thumbnails)! {
- if tn != nil {
- let info = KMTransitionInfo()
- info.thumbnail = tn
- info.label = "\(tn!.label)\(RIGHTARROW_CHARACTER)\(next.label)"
- info.properties = ptEnum?.nextObject() as? NSDictionary
- array.append(info)
- (cell as AnyObject).setStringValue(info.label)
- labelWidth = max(labelWidth, ceil(((cell as AnyObject).cellSize?.width)!))
- }
- tn = next
- }
-
- labelWidth = min(labelWidth, MAX_PAGE_COLUMN_WIDTH)
- tableColumn?.minWidth = labelWidth
- tableColumn?.maxWidth = labelWidth
- tableColumn?.width = labelWidth
-
- var frame: NSRect = tableView?.enclosingScrollView?.frame ?? .zero
- let wi: CGFloat = 61//tableColumn?.value(forKeyPath: "@sum.width") as! CGFloat
- frame.size.width = 19.0 + wi
- tableView?.enclosingScrollView?.frame = frame
-
- transitions = array as NSArray
- }
- override var windowNibName: NSNib.Name?{
- return "TransitionSheet"
- }
-
- func changePageTransitionType() {
- // SKImageToolTipWindow.sharedToolTipWindow().orderOut(nil)
- let window = self.window
- let isVisible = window?.isVisible ?? false
- var frame = window?.frame ?? NSRect.zero
- let scrollView = tableView?.enclosingScrollView
- var extraWidth: CGFloat
- let firstResponder = window?.firstResponder
- var editor: NSTextView? = nil
-
- if let textView = firstResponder as? NSTextView {
- editor = textView
- if textView.isFieldEditor {
- // firstResponder = textView.delegate
- }
- }
-
- if let editor = editor, window?.firstResponder != editor {
- window?.makeFirstResponder(firstResponder)
- }
-
- if separate {
- makeTransitions()
-
- extraWidth = (scrollView?.frame.width ?? 0) + TABLE_OFFSET
- frame.size.width += extraWidth
- frame.origin.x -= floor(0.5 * extraWidth)
- window?.setFrame(frame, display: isVisible, animate: isVisible)
- scrollView?.isHidden = false
- } else {
- scrollView?.isHidden = true
- extraWidth = (scrollView?.frame.width ?? 0) + TABLE_OFFSET
- frame.size.width -= extraWidth
- frame.origin.x += floor(0.5 * extraWidth)
- window?.setFrame(frame, display: isVisible, animate: isVisible)
- }
-
- // (undoRedoManager.prepare(withInvocationTarget: self) as AnyObject).separate = sparate == fasle
-
- }
-
- @IBAction func pageTransitionAction(_ sender: NSButton) {
- separate = sender.state == .on
-
- changePageTransitionType()
- }
-
-
- @IBAction func changeDurationSlider(_ sender: NSSlider) {
- self.durationTF.stringValue = sender.stringValue
- }
- @IBAction func cancelAction(_ sender: Any) {
- if let handle = closeCallBack {
- handle(self)
- }
- }
- @IBAction func okAction(_ sender: Any) {
- if let handle = closeCallBack {
- handle(self)
- }
- if ((undoManager?.canUndo) != nil) {
- transitionController?.transitionStyle = transition.transitionStyle
- transitionController?.duration = CGFloat(transition.duration)
- transitionController?.shouldRestrict = transition.shouldRestrict
- transitionController?.pageTransitions = pageTransitions as? [Any]
- (controller?.undoManager)?.setActionName(NSLocalizedString("Change Transitions", comment: "Undo action name"))
- }
- controller?.myDocument/*presentationNotesDocument*/ = notesDocument
- }
-
- func windowWillReturnUndoManager(_ window: NSWindow) -> UndoManager? {
- return undoRedoManager
- }
-
- func setValue(_ value: Any?, forKey key: String, ofTransition info: KMTransitionInfo) {
- info.setValue(value, forKey: key)
- }
- override class func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
- if context == &SKTransitionPropertiesObservationContext {
- guard let info = object as? KMTransitionInfo else {
- super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
- return
- }
- let newValue = change?[.newKey]
- let oldValue = change?[.oldKey]
-
- let newNonNullValue = newValue as? NSNull == nil ? newValue : nil
- let oldNonNullValue = oldValue as? NSNull == nil ? oldValue : nil
-
- // if (newNonNullValue != nil || oldNonNullValue != nil) && newNonNullValue != oldNonNullValue {
- // (undoManager?.prepare(withInvocationTarget: self) as AnyObject).setValue(oldNonNullValue, forKey: keyPath, ofTransition: info)
- // }
- if (newNonNullValue != nil || oldNonNullValue != nil){
-
- }
- } else {
- super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
- }
- }
- func numberOfRows(in tableView: NSTableView) -> Int {
- return 0
- }
- func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
- return nil
- }
- func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
- if rowIndexes.count == 1 {
- pboard.clearContents()
- pboard.writeObjects([transitions?[rowIndexes.first ?? 0] as! NSPasteboardWriting])
- return true
- } else {
- return false
- }
- }
-
- func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
- if info.draggingPasteboard.canReadObject(forClasses: [KMTransitionInfo.self], options: [:]) {
- if dropOperation == .above {
- tableView.setDropRow(-1, dropOperation: .on)
- }
- return .every
- }
- return []
- }
-
- func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
- let pboard = info.draggingPasteboard
- if dropOperation == .on {
- guard let infos = pboard.readObjects(forClasses: [KMTransitionInfo.self], options: [:]) as? [KMTransitionInfo], infos.count > 0 else {
- return false
- }
- let propertie: NSDictionary? = infos[0].properties
-
- if row == -1 {
- transitions?.setValue(propertie, forKey: PROPERTIES_KEY)
- } else {
- let transit: KMTransitionInfo = transitions?[row] as! KMTransitionInfo
- transit.properties = propertie
- }
- return true
- }
- return false
- }
- func tableView(_ aTableView: NSTableView, imageContextForRow rowIndex: Int) -> AnyObject? {
- return controller?.document?.page(at: UInt(rowIndex))
- }
-
- func tableView(_ aTableView: NSTableView, copyRowsWithIndexes rowIndexes: IndexSet) {
- let pboard = NSPasteboard.general
- pboard.clearContents()
- pboard.writeObjects([transitions?[rowIndexes.first ?? 0] as! NSPasteboardWriting])
- }
- func tableView(_ aTableView: NSTableView, canCopyRowsWithIndexes rowIndexes: IndexSet) -> Bool {
- return true
- }
- func tableView(_ aTableView: NSTableView, pasteFromPasteboard pboard: NSPasteboard) {
- guard let infos = pboard.readObjects(forClasses: [KMTransitionInfo.self], options: [:]) as? [KMTransitionInfo], infos.count > 0 else { return }
- let arr: NSArray = transitions?.objects(at: tableView.selectedRowIndexes) as! NSArray
- arr.setValue(infos[0].properties, forKey: PROPERTIES_KEY)
- }
- func tableView(_ aTableView: NSTableView, canPasteFromPasteboard pboard: NSPasteboard) -> Bool {
- return (tableView.selectedRow != -1 && pboard.canReadObject(forClasses: [KMTransitionInfo.self], options: [:]))
- }
- func tableView(_ aTableView: NSTableView, typeSelectHelperSelectionStrings aTypeSelectHelper: SKTypeSelectHelper) -> NSArray {
- return transitions?.value(forKeyPath: "thumbnail.label") as! NSArray
- }
- }
- //
|