// // KMPresentationTopViewController.swift // PDF Reader Pro // // Created by 丁林圭 on 2024/9/23. // import Cocoa import KMComponentLibrary @objc public protocol KMPresentationTopViewControllerDelegate: AnyObject { @objc optional func presentationTopViewExit(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) @objc optional func presentationTopViewUndo(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) @objc optional func presentationTopViewClear(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) @objc optional func presentationTopViewType(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton,isSeletion:Bool) @objc optional func presentationTopViewDrawColor(_ presentationTopViewController: KMPresentationTopViewController, withView: NSView,color:NSColor?) } public class KMPresentationTopViewController: NSViewController, KMDrawViewDelegate { @IBOutlet var pageNubLabel: NSTextField! @IBOutlet var backButton: NSButton! @IBOutlet var forwardButton: NSButton! @IBOutlet var undoButton: NSButton! @IBOutlet var exitButton: NSButton! @IBOutlet var deleteButton: NSButton! @IBOutlet var typeButton: NSButton! @IBOutlet var colorGroup: ComponentCColorGroup! public weak var pdfView: CPDFListView? public var isSelectionPre: Bool = true weak var delegate: KMPresentationTopViewControllerDelegate? var keyEventMonitor: Any? deinit { NSColorPanel.shared.setTarget(nil) NSColorPanel.shared.setAction(nil) removeKeyEventMonitor() } public override func viewDidLoad() { super.viewDidLoad() pageNubLabel.stringValue = "\((pdfView?.currentPageIndex ?? 0) + 1)/\(pdfView?.document.pageCount ?? 0)" NotificationCenter.default.addObserver(self, selector: #selector(pageChangedNotification(_:)), name: NSNotification.Name.CPDFViewPageChanged, object: self.pdfView) self.view.wantsLayer = true DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil) updateViewColor() if(isSelectionPre == false) { typeButton.image = NSImage(named: "KMPresentationImageNameType") } else { typeButton.image = NSImage(named: "KMPresentationImageNameTypeSeletion") } updatePageState() pdfView?.presentationDrawView.delegate = self undoButton.isEnabled = false (self.view as? KMHoverView)?.hoverAction = { view, act in if act == .enter { NSCursor.arrow.set() } else if act == .exit { } else { NSCursor.arrow.set() } } let colors = KMAnnotationPropertiesColorManager.manager.pptColors let colorAProperty = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: false, color: colors[0]) let colorBProperty = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: false, color: colors[1]) let colorCProperty = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: false, color: colors[2]) let colorDProperty = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: false, color: colors[3]) let colorEProperty = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: true, color: colors[4]) colorGroup.setUpWithColorPropertys([colorAProperty, colorBProperty, colorCProperty, colorDProperty], customItemProperty: colorEProperty) colorGroup.delegate = self addKeyEventMonitor() } func addKeyEventMonitor() { if (self.keyEventMonitor != nil) { self.removeKeyEventMonitor() } keyEventMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { [weak self] event in guard let self = self else { return event} if let mainVC = self.delegate as? KMMainViewController { if event.keyCode == 53 { self.buttonItemClicked_Exit(self.exitButton) } if mainVC.interactionMode == .presentation { // 幻灯片模式下 self.pdfView!.keyDown(with: event) return nil } } return event } } func removeKeyEventMonitor() { if (self.keyEventMonitor != nil) { KMPrint("removeKeyEventMonitor 已移除事件监听") NSEvent.removeMonitor(self.keyEventMonitor as Any) self.keyEventMonitor = nil } } // MARK: - Private private func updatePageState() { if(pdfView?.canGoToNextPage() == true) { backButton.isEnabled = true } else { backButton.isEnabled = false } if(pdfView?.canGoToPreviousPage() == true) { forwardButton.isEnabled = true } else { forwardButton.isEnabled = false } } private func updateViewColor() { let isDark = KMAppearance.isDarkMode() if isDark { self.view.layer?.backgroundColor = NSColor(hex: "#464646").cgColor } else { self.view.layer?.backgroundColor = NSColor.white.cgColor } } // MARK: - Action @IBAction func buttonItemClicked_BackPage(_ sender: NSButton) { updatePageState() if(pdfView?.canGoToNextPage() == true) { pdfView?.goToNextPage(sender) } } @IBAction func buttonItemClicked_ForwardPage(_ sender: NSButton) { updatePageState() if(pdfView?.canGoToPreviousPage() == true) { pdfView?.goToPreviousPage(sender) } } @IBAction func buttonItemClicked_Undo(_ sender: NSButton) { delegate?.presentationTopViewUndo?(self, withButton: sender) } @IBAction func buttonItemClicked_Exit(_ sender: NSButton) { delegate?.presentationTopViewExit?(self, withButton: sender) } @IBAction func buttonItemClicked_Delete(_ sender: NSButton) { delegate?.presentationTopViewClear?(self, withButton: sender) } @IBAction func buttonItemClicked_Type(_ sender: NSButton) { if(isSelectionPre == true) { typeButton.image = NSImage(named: "KMPresentationImageNameType") isSelectionPre = false } else { typeButton.image = NSImage(named: "KMPresentationImageNameTypeSeletion") isSelectionPre = true } undoButton.isEnabled = false colorGroup.currentColor = nil colorGroup.refreshUI() delegate?.presentationTopViewType?(self, withButton: sender, isSeletion: isSelectionPre) } // MARK: - Notification @objc func pageChangedNotification(_ notification: Notification) { guard let pdfview = notification.object as? CPDFView else { return } if pdfview.document == self.pdfView?.document { pageNubLabel.stringValue = "\((pdfView?.currentPageIndex ?? 0) + 1)/\(pdfView?.document.pageCount ?? 0)" updatePageState() let presentationDrawView = pdfView?.presentationDrawView presentationDrawView?.clear() // presentationDrawView?.resetUndoManager() } } @objc func themeChanged(notification: Notification) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.updateViewColor() } } // MARK: - KMDrawView public func drawView(_ drawView: KMDrawView!, didUpdateUndoStatus enable: Bool) { undoButton.isEnabled = enable } public func drawView(_ drawView: KMDrawView!, didDrawEnd point: CGPoint) { undoButton.isEnabled = ((pdfView?.presentationDrawView.canUndo()) == true) } } // MARK: - ComponentCColorDelegate extension KMPresentationTopViewController: ComponentCColorDelegate { public func componentCColorDidChooseColor(_ view: NSView, _ color: NSColor?) { if let borderColor = color { if (isSelectionPre == true) { typeButton.image = NSImage(named: "KMPresentationImageNameType") isSelectionPre = false } undoButton.isEnabled = false delegate?.presentationTopViewDrawColor?(self, withView: view, color: borderColor) } } }