|
@@ -0,0 +1,722 @@
|
|
|
+//
|
|
|
+// KMPageDisplayPropertiesViewController.swift
|
|
|
+// PDF Master
|
|
|
+//
|
|
|
+// Created by wanjun on 2024/1/1.
|
|
|
+//
|
|
|
+
|
|
|
+import Cocoa
|
|
|
+
|
|
|
+typealias ReaderModeCallBack = (Bool) -> Void
|
|
|
+
|
|
|
+private enum KMDisplayModeType: UInt {
|
|
|
+ case singlePage = 0
|
|
|
+ case twoPages
|
|
|
+ case coverPage
|
|
|
+ case readMode
|
|
|
+}
|
|
|
+
|
|
|
+private enum KMSplitViewType: UInt {
|
|
|
+ case singleScreen = 0
|
|
|
+ case verticalScreen
|
|
|
+ case horizontalScreen
|
|
|
+}
|
|
|
+
|
|
|
+class KMPageDisplayPropertiesButton: NSButton {
|
|
|
+ var buttonBorderColor: NSColor?
|
|
|
+ var buttonLayerRadius: CGFloat = 0.0
|
|
|
+
|
|
|
+ deinit {
|
|
|
+ buttonBorderColor = nil
|
|
|
+ }
|
|
|
+
|
|
|
+ override init(frame frameRect: NSRect) {
|
|
|
+ super.init(frame: frameRect)
|
|
|
+ wantsLayer = true
|
|
|
+ layer?.cornerRadius = 6.0
|
|
|
+ }
|
|
|
+
|
|
|
+ required init?(coder: NSCoder) {
|
|
|
+ super.init(coder: coder)
|
|
|
+ wantsLayer = true
|
|
|
+ layer?.cornerRadius = 6.0
|
|
|
+ }
|
|
|
+
|
|
|
+ override func draw(_ dirtyRect: NSRect) {
|
|
|
+ super.draw(dirtyRect)
|
|
|
+ // Custom drawing code here
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@objcMembers class KMPageDisplayPropertiesViewController: NSViewController {
|
|
|
+
|
|
|
+ @IBOutlet weak var pdfView: CPDFListView!
|
|
|
+ var readerModeBlock: ReaderModeCallBack?
|
|
|
+ @IBOutlet weak var mainController: KMMainViewController!
|
|
|
+
|
|
|
+ @IBOutlet private var pageLayoutLabel: NSTextField!
|
|
|
+ @IBOutlet private var singlePageButton: KMPageDisplayPropertiesButton!
|
|
|
+ @IBOutlet private var twoPagesButton: KMPageDisplayPropertiesButton!
|
|
|
+ @IBOutlet private var coverPageButton: KMPageDisplayPropertiesButton!
|
|
|
+ @IBOutlet private var readModeButton: KMPageDisplayPropertiesButton!
|
|
|
+ @IBOutlet private var continuousScrollButton: NSButton!
|
|
|
+ @IBOutlet private var pageBreaksButton: NSButton!
|
|
|
+ @IBOutlet private var pageDisplayHeightConstraint: NSLayoutConstraint!
|
|
|
+
|
|
|
+ // Split View Properties
|
|
|
+ @IBOutlet private var splitViewLabel: NSTextField!
|
|
|
+ @IBOutlet private var singleScreenButton: KMPageDisplayPropertiesButton!
|
|
|
+ @IBOutlet private var verticalScreenButton: KMPageDisplayPropertiesButton!
|
|
|
+ @IBOutlet private var horizontalScreenButton: KMPageDisplayPropertiesButton!
|
|
|
+ @IBOutlet private var replaceViewTopConstraint: NSLayoutConstraint!
|
|
|
+ @IBOutlet private var replaceView: NSView!
|
|
|
+ @IBOutlet private var replaceFileNameLabel: NSTextField!
|
|
|
+ @IBOutlet private var replaceFileButton: NSButton!
|
|
|
+ @IBOutlet private var buttonHeightConstraint2: NSLayoutConstraint!
|
|
|
+
|
|
|
+ // Rotation Properties
|
|
|
+ @IBOutlet private var rotationLabel: NSTextField!
|
|
|
+ @IBOutlet private var clockwiseRotationBox: KMBox!
|
|
|
+ @IBOutlet private var clockwiseRotationImageView: NSImageView!
|
|
|
+ @IBOutlet private var counterclockwiseRotationBox: KMBox!
|
|
|
+ @IBOutlet private var counterclockwiseRotationImageView: NSImageView!
|
|
|
+
|
|
|
+ // Theme Properties
|
|
|
+ @IBOutlet private var themeLabel: NSTextField!
|
|
|
+ @IBOutlet private var themeCollectionView: NSCollectionView!
|
|
|
+ @IBOutlet private var themeScrollView: NSScrollView!
|
|
|
+ @IBOutlet private var collectionLayoutCollection: NSLayoutConstraint!
|
|
|
+
|
|
|
+ // Other Properties
|
|
|
+ private var displayMode: KMDisplayModeType = .singlePage
|
|
|
+ private var isReaderMode: Bool = false
|
|
|
+ private var isContinuPage: Bool = false
|
|
|
+ private var splitViewType: KMSplitViewType = .singleScreen
|
|
|
+ private var themesArray: [NSColor] = []
|
|
|
+ private var clickInteger: Int = 0
|
|
|
+ private var displayType: KMPDFDisplayType = .singlePage
|
|
|
+
|
|
|
+ // MARK: - Init Method
|
|
|
+
|
|
|
+ deinit {
|
|
|
+ NotificationCenter.default.removeObserver(self)
|
|
|
+ themeCollectionView.delegate = nil
|
|
|
+ themeCollectionView.dataSource = nil
|
|
|
+// let keys = ["displaysAsBook", "displayMode"]
|
|
|
+// for key in keys {
|
|
|
+// pdfView.removeObserver(self, forKeyPath: key)
|
|
|
+// }
|
|
|
+ }
|
|
|
+
|
|
|
+ override func viewDidLoad() {
|
|
|
+ super.viewDidLoad()
|
|
|
+ // Do view setup here.
|
|
|
+
|
|
|
+ themeCollectionView.register(KMPageDisplayThemeCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMPageDisplayThemeCollectionViewItem"))
|
|
|
+ themeCollectionView.register(KMPageDisplayCustomThemesCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMPageDisplayCustomThemesCollectionViewItem"))
|
|
|
+
|
|
|
+ pageLayoutLabel.stringValue = NSLocalizedString("Display Mode", comment: "")
|
|
|
+ pageLayoutLabel.textColor = KMAppearance.Layout.h0Color()
|
|
|
+ singlePageButton.title = NSLocalizedString("Single Page", comment: "Menu item title")
|
|
|
+ singlePageButton.toolTip = NSLocalizedString("Single Page", comment: "Menu item title")
|
|
|
+ singlePageButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagesingleNor)
|
|
|
+ singlePageButton.wantsLayer = true
|
|
|
+ twoPagesButton.title = NSLocalizedString("Two Pages", comment: "Menu item title")
|
|
|
+ twoPagesButton.toolTip = NSLocalizedString("Two Pages", comment: "Menu item title")
|
|
|
+ twoPagesButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagedoubleNor)
|
|
|
+ twoPagesButton.wantsLayer = true
|
|
|
+ coverPageButton.title = NSLocalizedString("Book Mode", comment: "")
|
|
|
+ coverPageButton.toolTip = NSLocalizedString("Book Mode", comment: "")
|
|
|
+ coverPageButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagecoverNor)
|
|
|
+ coverPageButton.wantsLayer = true
|
|
|
+ readModeButton.title = NSLocalizedString("Read Mode", comment: "Menu item title")
|
|
|
+ readModeButton.toolTip = NSLocalizedString("Read Mode", comment: "Menu item title")
|
|
|
+ readModeButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagereadingNor)
|
|
|
+ readModeButton.wantsLayer = true
|
|
|
+ continuousScrollButton.title = NSLocalizedString("Continuous Scroll", comment: "")
|
|
|
+ pageBreaksButton.title = NSLocalizedString("Page Breaks", comment: "")
|
|
|
+
|
|
|
+ splitViewLabel.stringValue = NSLocalizedString("Split View", comment: "")
|
|
|
+ splitViewLabel.textColor = KMAppearance.Layout.h0Color()
|
|
|
+ singleScreenButton.title = NSLocalizedString("Single", comment: "")
|
|
|
+ singleScreenButton.toolTip = NSLocalizedString("Single", comment: "")
|
|
|
+ singleScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreensingleNor)
|
|
|
+ singleScreenButton.wantsLayer = true
|
|
|
+ verticalScreenButton.title = NSLocalizedString("Vertical", comment: "")
|
|
|
+ verticalScreenButton.toolTip = NSLocalizedString("Vertical", comment: "")
|
|
|
+ verticalScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreenverNor)
|
|
|
+ verticalScreenButton.wantsLayer = true
|
|
|
+ horizontalScreenButton.title = NSLocalizedString("Horizontal", comment: "")
|
|
|
+ horizontalScreenButton.toolTip = NSLocalizedString("Horizontal", comment: "")
|
|
|
+ horizontalScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreenhorNor)
|
|
|
+ horizontalScreenButton.wantsLayer = true
|
|
|
+
|
|
|
+ if let documentPath = self.mainController.secondaryPdfView.document?.documentURL?.path {
|
|
|
+ replaceView.isHidden = false
|
|
|
+ } else {
|
|
|
+ replaceView.isHidden = true
|
|
|
+ }
|
|
|
+
|
|
|
+ replaceFileButton.wantsLayer = true
|
|
|
+ replaceFileButton.layer?.cornerRadius = 4.0
|
|
|
+ replaceFileButton.layer?.backgroundColor = KMAppearance.Interactive.a0Color().cgColor
|
|
|
+ reloadReplaceView()
|
|
|
+
|
|
|
+// self.mainController.secondaryFileUrlBlock = { [weak self] in
|
|
|
+// guard let self = self else { return }
|
|
|
+// self.replaceView.isHidden = false
|
|
|
+// self.reloadReplaceView()
|
|
|
+// self.replaceFileButton.titleColor = KMAppearance.Layout.w0Color()
|
|
|
+// self.replaceViewTopConstraint.constant = self.replaceView.isHidden ? -self.replaceView.bounds.height : 10.0
|
|
|
+// }
|
|
|
+
|
|
|
+ replaceFileNameLabel.cell?.lineBreakMode = .byTruncatingMiddle
|
|
|
+ replaceFileNameLabel.cell?.truncatesLastVisibleLine = true
|
|
|
+
|
|
|
+ rotationLabel.stringValue = NSLocalizedString("Rotate", comment: "")
|
|
|
+ rotationLabel.textColor = KMAppearance.Layout.h0Color()
|
|
|
+
|
|
|
+ counterclockwiseRotationBox.borderColor = KMAppearance.Interactive.s0Color()
|
|
|
+ counterclockwiseRotationBox.borderWidth = 1.0
|
|
|
+ counterclockwiseRotationBox.fillColor = KMAppearance.Layout.l1Color()
|
|
|
+ counterclockwiseRotationBox.cornerRadius = 1.0
|
|
|
+ counterclockwiseRotationBox.toolTip = NSLocalizedString("Rotate Left", comment: "")
|
|
|
+ counterclockwiseRotationImageView.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwiseNor)
|
|
|
+
|
|
|
+ counterclockwiseRotationBox.downCallback = { [weak self] downEntered, mouseBox, event in
|
|
|
+ guard let self = self else { return }
|
|
|
+ if downEntered {
|
|
|
+ counterclockwiseRotationBox.fillColor = KMAppearance.Status.selColor()
|
|
|
+ counterclockwiseRotationImageView.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwisePre)
|
|
|
+ mainController.menuItemAction_rotateLeft((Any).self)
|
|
|
+ } else {
|
|
|
+ self.counterclockwiseRotationBox.fillColor = KMAppearance.Layout.l1Color()
|
|
|
+ self.counterclockwiseRotationImageView.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwiseNor)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ clockwiseRotationBox.borderColor = KMAppearance.Interactive.s0Color()
|
|
|
+ clockwiseRotationBox.borderWidth = 1.0
|
|
|
+ clockwiseRotationBox.fillColor = KMAppearance.Layout.l1Color()
|
|
|
+ clockwiseRotationBox.cornerRadius = 1.0
|
|
|
+ clockwiseRotationBox.toolTip = NSLocalizedString("Rotate Right", comment: "")
|
|
|
+ clockwiseRotationImageView.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwiseNor)
|
|
|
+
|
|
|
+ clockwiseRotationBox.downCallback = { [weak self] downEntered, mouseBox, event in
|
|
|
+ guard let self = self else { return }
|
|
|
+ if downEntered {
|
|
|
+ clockwiseRotationBox.fillColor = KMAppearance.Status.selColor()
|
|
|
+ clockwiseRotationImageView.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwisePre)
|
|
|
+ mainController.menuItemAction_rotateRight((Any).self)
|
|
|
+ } else {
|
|
|
+ clockwiseRotationBox.fillColor = KMAppearance.Layout.l1Color()
|
|
|
+ clockwiseRotationImageView.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwiseNor)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ themeLabel.stringValue = NSLocalizedString("Themes", comment: "")
|
|
|
+ themeLabel.textColor = KMAppearance.Layout.h0Color()
|
|
|
+
|
|
|
+ let buttonArr: [NSButton] = [singlePageButton, twoPagesButton, coverPageButton, readModeButton, continuousScrollButton, singleScreenButton, verticalScreenButton, horizontalScreenButton]
|
|
|
+
|
|
|
+ for button in buttonArr {
|
|
|
+ if let attrTitle = button.attributedTitle.mutableCopy() as? NSMutableAttributedString {
|
|
|
+ let len = attrTitle.length
|
|
|
+ let range = NSRange(location: 0, length: len)
|
|
|
+ attrTitle.addAttribute(NSAttributedString.Key.foregroundColor, value: KMAppearance.Layout.h0Color(), range: range)
|
|
|
+ attrTitle.fixAttributes(in: range)
|
|
|
+ button.attributedTitle = attrTitle
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var data: Data? = nil
|
|
|
+ if let themesData = UserDefaults.standard.object(forKey: "kKMPDFViewModeThemesArray") as? Data {
|
|
|
+ data = themesData
|
|
|
+ }
|
|
|
+
|
|
|
+ let appArray = NSKeyedUnarchiver.unarchiveObject(with: data ?? Data()) as? [Any] ?? []
|
|
|
+ var mutableArray = appArray
|
|
|
+ if mutableArray.count > 0 {
|
|
|
+ themesArray = mutableArray as! [NSColor]
|
|
|
+ } else {
|
|
|
+ let normalColor = NSColor.white
|
|
|
+ let softColor = NSColor(deviceRed: 238.0/255.0, green: 232.0/255.0, blue: 216.0/255.0, alpha: 1.0)
|
|
|
+ let nightColor = NSColor.black
|
|
|
+ let greenColor = NSColor(deviceRed: 153.0/255.0, green: 207.0/255.0, blue: 161.0/255.0, alpha: 1.0)
|
|
|
+ themesArray = [normalColor, softColor, nightColor, greenColor]
|
|
|
+ }
|
|
|
+
|
|
|
+ themeScrollView.backgroundColor = .clear
|
|
|
+ themeCollectionView.delegate = self
|
|
|
+ themeCollectionView.dataSource = self
|
|
|
+ reloadData()
|
|
|
+
|
|
|
+ NotificationCenter.default.addObserver(self, selector: #selector(viewModeChangNotification(_:)), name: NSNotification.Name("KMPDFViewModeChangeNotification"), object: nil)
|
|
|
+
|
|
|
+ let languages = NSLocale.preferredLanguages
|
|
|
+ var currentLocaleLanguageCode = "en"
|
|
|
+ if languages.count > 0 {
|
|
|
+ currentLocaleLanguageCode = languages[0]
|
|
|
+ if currentLocaleLanguageCode.hasPrefix("zh") {
|
|
|
+ currentLocaleLanguageCode = "zh"
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let buttonArray1: [NSButton] = [singlePageButton, twoPagesButton, coverPageButton, readModeButton]
|
|
|
+ for button in buttonArray1 {
|
|
|
+ button.wantsLayer = true
|
|
|
+ button.layer?.cornerRadius = 6.0
|
|
|
+ if currentLocaleLanguageCode == "zh" {
|
|
|
+ pageDisplayHeightConstraint.constant = 56.0
|
|
|
+ button.imagePosition = .imageAbove
|
|
|
+ } else {
|
|
|
+ pageDisplayHeightConstraint.constant = singlePageButton.bounds.width
|
|
|
+ button.imagePosition = .imageOnly
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let buttonArray2: [NSButton] = [singleScreenButton, verticalScreenButton, horizontalScreenButton]
|
|
|
+ for button in buttonArray2 {
|
|
|
+ button.wantsLayer = true
|
|
|
+ button.layer?.cornerRadius = 6.0
|
|
|
+ if currentLocaleLanguageCode == "zh" {
|
|
|
+ pageDisplayHeightConstraint.constant = 56.0
|
|
|
+ button.imagePosition = .imageAbove
|
|
|
+ } else {
|
|
|
+ pageDisplayHeightConstraint.constant = singleScreenButton.bounds.width
|
|
|
+ button.imagePosition = .imageOnly
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ replaceFileButton?.setTitleColor(KMAppearance.Layout.w0Color())
|
|
|
+
|
|
|
+ replaceViewTopConstraint.constant = replaceView.isHidden ? -replaceView.bounds.height : 10.0
|
|
|
+
|
|
|
+ NotificationCenter.default.addObserver(self, selector: #selector(removeSecondaryPdfContentView(_:)), name: NSNotification.Name("KMSplitSinglePageNotification"), object: nil)
|
|
|
+ }
|
|
|
+
|
|
|
+ private func reloadReplaceView() {
|
|
|
+ if let documentPath = mainController.secondaryPdfView.document?.documentURL?.path {
|
|
|
+ replaceFileButton.title = NSLocalizedString("Replace File", comment: "")
|
|
|
+ replaceFileButton.toolTip = NSLocalizedString("Replace File", comment: "")
|
|
|
+ replaceFileNameLabel.attributedStringValue = replaceFileName(withFilePath: (documentPath as NSString).lastPathComponent)
|
|
|
+ replaceFileNameLabel.isHidden = false
|
|
|
+ } else {
|
|
|
+ replaceFileButton.title = NSLocalizedString("Select File", comment: "")
|
|
|
+ replaceFileButton.toolTip = NSLocalizedString("Select File", comment: "")
|
|
|
+ replaceFileNameLabel.attributedStringValue = replaceFileName(withFilePath: "")
|
|
|
+ replaceFileNameLabel.isHidden = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private func reloadData() {
|
|
|
+ let pdf: CPDFView = CPDFView()
|
|
|
+ if displayType == .singlePage {
|
|
|
+ setDisplayMode(.singlePage)
|
|
|
+ continuousScrollButton.state = .off
|
|
|
+ } else if displayType == .singlePageContinuous {
|
|
|
+ setDisplayMode(.singlePage)
|
|
|
+ continuousScrollButton.state = .on
|
|
|
+ isContinuPage = true
|
|
|
+ } else if displayType == .twoUp {
|
|
|
+ if pdfView.displaysAsBook {
|
|
|
+ setDisplayMode(.coverPage)
|
|
|
+ } else {
|
|
|
+ setDisplayMode(.twoPages)
|
|
|
+ }
|
|
|
+ continuousScrollButton.state = .off
|
|
|
+ } else if displayType == .twoUpContinuous {
|
|
|
+ if pdfView.displaysAsBook {
|
|
|
+ setDisplayMode(.coverPage)
|
|
|
+ } else {
|
|
|
+ setDisplayMode(.twoPages)
|
|
|
+ }
|
|
|
+ continuousScrollButton.state = .on
|
|
|
+ isContinuPage = true
|
|
|
+ }
|
|
|
+
|
|
|
+ isReaderMode = UserDefaults.standard.bool(forKey: "kKMPDFViewIsReadMode")
|
|
|
+ if isReaderMode {
|
|
|
+ setDisplayMode(.readMode)
|
|
|
+ }
|
|
|
+
|
|
|
+ if pdfView.displaysPageBreaks {
|
|
|
+ pageBreaksButton.state = .on
|
|
|
+ } else {
|
|
|
+ pageBreaksButton.state = .off
|
|
|
+ }
|
|
|
+
|
|
|
+ if !(mainController.secondaryPdfView.window != nil) {
|
|
|
+ setSplitViewType(.singleScreen)
|
|
|
+ } else {
|
|
|
+ if mainController.pdfSplitView.isVertical {
|
|
|
+ setSplitViewType(.verticalScreen)
|
|
|
+ } else {
|
|
|
+ setSplitViewType(.horizontalScreen)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ themeCollectionView.reloadData()
|
|
|
+ }
|
|
|
+
|
|
|
+// private func setPdfView(_ pdfView: SKPDFView) {
|
|
|
+// if _pdfView !== pdfView {
|
|
|
+// let keys = ["displaysAsBook", "displayMode"]
|
|
|
+//
|
|
|
+// for key in keys {
|
|
|
+// _pdfView?.removeObserver(self, forKeyPath: key)
|
|
|
+// }
|
|
|
+//
|
|
|
+// _pdfView?.release()
|
|
|
+// _pdfView = pdfView
|
|
|
+// _pdfView?.retain()
|
|
|
+//
|
|
|
+// for key in keys {
|
|
|
+// _pdfView?.addObserver(self, forKeyPath: key, options: [.new, .old], context: nil)
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+ // MARK: - Private
|
|
|
+
|
|
|
+ private func setDisplayMode(_ displayMode: KMDisplayModeType) {
|
|
|
+ self.displayMode = displayMode
|
|
|
+ switch displayMode {
|
|
|
+ case .singlePage:
|
|
|
+ singlePageButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagesingleSel)
|
|
|
+ singlePageButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
|
|
|
+
|
|
|
+ twoPagesButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagedoubleNor)
|
|
|
+ twoPagesButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+
|
|
|
+ coverPageButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagecoverNor)
|
|
|
+ coverPageButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+ case .twoPages:
|
|
|
+ twoPagesButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagedoubleSel)
|
|
|
+ twoPagesButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
|
|
|
+
|
|
|
+ singlePageButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagesingleNor)
|
|
|
+ singlePageButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+
|
|
|
+ coverPageButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagecoverNor)
|
|
|
+ coverPageButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+ case .coverPage:
|
|
|
+ coverPageButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagecoverSel)
|
|
|
+ coverPageButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
|
|
|
+
|
|
|
+ singlePageButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagesingleNor)
|
|
|
+ singlePageButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+
|
|
|
+ twoPagesButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagedoubleNor)
|
|
|
+ twoPagesButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+ case .readMode:
|
|
|
+ self.isReaderMode = !self.isReaderMode
|
|
|
+ if self.isReaderMode {
|
|
|
+ readModeButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagereadingSel)
|
|
|
+ readModeButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
|
|
|
+ } else {
|
|
|
+ readModeButton.image = NSImage(named: KMImageNameUXIconPropertybarViewPagereadingNor)
|
|
|
+ readModeButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private func setSplitViewType(_ splitViewType: KMSplitViewType) {
|
|
|
+ self.splitViewType = splitViewType
|
|
|
+ switch splitViewType {
|
|
|
+ case .singleScreen:
|
|
|
+ singleScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreensingleSel)
|
|
|
+ singleScreenButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
|
|
|
+
|
|
|
+ verticalScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreenverNor)
|
|
|
+ verticalScreenButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+
|
|
|
+ horizontalScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreenhorNor)
|
|
|
+ horizontalScreenButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+ case .verticalScreen:
|
|
|
+ verticalScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreenverSel)
|
|
|
+ verticalScreenButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
|
|
|
+
|
|
|
+ singleScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreensingleNor)
|
|
|
+ singleScreenButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+
|
|
|
+ horizontalScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreenhorNor)
|
|
|
+ horizontalScreenButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+ case .horizontalScreen:
|
|
|
+ horizontalScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreenhorSel)
|
|
|
+ horizontalScreenButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
|
|
|
+
|
|
|
+ verticalScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreenverNor)
|
|
|
+ verticalScreenButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+
|
|
|
+ singleScreenButton.image = NSImage(named: KMImageNameUXIconPropertybarViewSplitscreensingleNor)
|
|
|
+ singleScreenButton.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private func replaceFileName(withFilePath filePath: String) -> NSMutableAttributedString {
|
|
|
+ let string = "· \(filePath)"
|
|
|
+ let attrStr = NSMutableAttributedString(string: string)
|
|
|
+
|
|
|
+ attrStr.addAttribute(.foregroundColor, value: KMAppearance.Interactive.a0Color(), range: NSRange(location: 0, length: 1))
|
|
|
+ attrStr.addAttribute(.font, value: NSFont.boldSystemFont(ofSize: 20), range: NSRange(location: 0, length: 1))
|
|
|
+ attrStr.addAttribute(.baselineOffset, value: 3, range: NSRange(location: 1, length: string.count - 1))
|
|
|
+
|
|
|
+ return attrStr
|
|
|
+ }
|
|
|
+
|
|
|
+ // MARK: UI Action
|
|
|
+
|
|
|
+ @IBAction private func displayModeButtonAction(_ sender: KMPageDisplayPropertiesButton) {
|
|
|
+ switch sender.tag {
|
|
|
+ case 0:
|
|
|
+ setDisplayMode(.singlePage)
|
|
|
+ mainController.selectDisplay(display: isContinuPage ? .singlePageContinuous : .singlePage, viewSettingIsReload: false)
|
|
|
+ case 1:
|
|
|
+ setDisplayMode(.twoPages)
|
|
|
+ mainController.selectDisplay(display: isContinuPage ? .twoUpContinuous : .twoUp, viewSettingIsReload: false)
|
|
|
+ case 2:
|
|
|
+ setDisplayMode(.coverPage)
|
|
|
+ mainController.selectDisplay(display: isContinuPage ? .bookContinuous : .bookMode, viewSettingIsReload: false)
|
|
|
+ case 3:
|
|
|
+// readerModeBlock?(isReaderMode)
|
|
|
+ mainController.selectDisplay(display: isContinuPage ? .readContinuous : .readModel, viewSettingIsReload: false)
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @IBAction private func continuousScrollButtonAction(_ sender: NSButton) {
|
|
|
+ isContinuPage = !isContinuPage
|
|
|
+
|
|
|
+ if isContinuPage {
|
|
|
+ if displayMode == KMDisplayModeType.singlePage {
|
|
|
+ mainController.selectDisplay(display: .singlePageContinuous, viewSettingIsReload: false)
|
|
|
+ } else {
|
|
|
+ mainController.selectDisplay(display: .twoUpContinuous, viewSettingIsReload: false)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if displayMode == KMDisplayModeType.singlePage {
|
|
|
+ mainController.selectDisplay(display: .singlePage, viewSettingIsReload: false)
|
|
|
+ } else {
|
|
|
+ mainController.selectDisplay(display: .twoUp, viewSettingIsReload: false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @IBAction private func pageBreaksButtonAction(_ sender: NSButton) {
|
|
|
+ pdfView.displaysPageBreaks = (pageBreaksButton.state == .on)
|
|
|
+ pdfView.layoutDocumentView()
|
|
|
+ }
|
|
|
+
|
|
|
+ @IBAction private func splitViewButtonAction(_ sender: KMPageDisplayPropertiesButton) {
|
|
|
+// if sender.tag > 0 && !IAPProductsManager.defaultManager().isAvailableAllFunction {
|
|
|
+// KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
|
|
|
+// return
|
|
|
+// }
|
|
|
+
|
|
|
+ let menuItem = NSMenuItem()
|
|
|
+ switch sender.tag {
|
|
|
+ case 0:
|
|
|
+ setSplitViewType(.singleScreen)
|
|
|
+ menuItem.tag = 2
|
|
|
+ replaceView.isHidden = true
|
|
|
+ case 1:
|
|
|
+ setSplitViewType(.verticalScreen)
|
|
|
+ menuItem.tag = 1
|
|
|
+ if let documentPath = mainController.secondaryPdfView.document?.documentURL?.path, !documentPath.isEmpty {
|
|
|
+ replaceView.isHidden = false
|
|
|
+ }
|
|
|
+ case 2:
|
|
|
+ setSplitViewType(.horizontalScreen)
|
|
|
+ menuItem.tag = 0
|
|
|
+ if let documentPath = mainController.secondaryPdfView.document?.documentURL?.path, !documentPath.isEmpty {
|
|
|
+ replaceView.isHidden = false
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ mainController.toggleSplitPDF(menuItem)
|
|
|
+
|
|
|
+ if !replaceView.isHidden {
|
|
|
+ reloadReplaceView()
|
|
|
+ replaceFileButton.setTitleColor(KMAppearance.Layout.w0Color())
|
|
|
+ }
|
|
|
+
|
|
|
+ replaceViewTopConstraint.constant = replaceView.isHidden ? -replaceView.bounds.height : 10.0
|
|
|
+ }
|
|
|
+
|
|
|
+ @IBAction private func replaceFileButtonAction(_ sender: Any) {
|
|
|
+ if let document = mainController.secondaryPdfView.document {
|
|
|
+ mainController.changePDFDocument(isChange: false) { [weak self] filePath in
|
|
|
+ self!.replaceFileNameLabel.attributedStringValue = self!.replaceFileName(withFilePath: (filePath as NSString).lastPathComponent)
|
|
|
+ self!.replaceFileNameLabel.isHidden = false
|
|
|
+ if self!.replaceFileButton.title == NSLocalizedString("Select File", comment: "") {
|
|
|
+ self!.replaceFileButton.title = NSLocalizedString("Replace File", comment: "")
|
|
|
+ self!.replaceFileButton.toolTip = NSLocalizedString("Replace File", comment: "")
|
|
|
+ self!.replaceFileButton.setTitleColor(KMAppearance.Layout.w0Color())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ mainController.changePDFDocument(isChange: true) { [weak self] filePath in
|
|
|
+ self!.replaceFileNameLabel.attributedStringValue = self!.replaceFileName(withFilePath: (filePath as NSString).lastPathComponent)
|
|
|
+ self!.replaceFileNameLabel.isHidden = false
|
|
|
+ if self!.replaceFileButton.title == NSLocalizedString("Select File", comment: "") {
|
|
|
+ self!.replaceFileButton.title = NSLocalizedString("Replace File", comment: "")
|
|
|
+ self!.replaceFileButton.toolTip = NSLocalizedString("Replace File", comment: "")
|
|
|
+ self!.replaceFileButton.setTitleColor(KMAppearance.Layout.w0Color())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // MARK: NSNotification Action
|
|
|
+
|
|
|
+ @objc func viewModeChangNotification(_ notification: Notification) {
|
|
|
+ reloadData()
|
|
|
+ }
|
|
|
+
|
|
|
+// override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
|
|
+// guard let object = object as? YourObjectType, keyPath == "yourKeyPath" else {
|
|
|
+// return
|
|
|
+// }
|
|
|
+//
|
|
|
+// guard let newValue = change?[.newKey] ?? NSNull(),
|
|
|
+// let oldValue = change?[.oldKey] ?? NSNull(),
|
|
|
+// newValue != oldValue else {
|
|
|
+// return
|
|
|
+// }
|
|
|
+//
|
|
|
+// reloadData()
|
|
|
+// }
|
|
|
+
|
|
|
+ @objc func removeSecondaryPdfContentView(_ notification: Notification) {
|
|
|
+ setSplitViewType(.singleScreen)
|
|
|
+ replaceView.isHidden = true
|
|
|
+ replaceViewTopConstraint.constant = replaceView.isHidden ? -replaceView.bounds.height : 10.0
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+extension KMPageDisplayPropertiesViewController: NSCollectionViewDelegate, NSCollectionViewDataSource {
|
|
|
+ func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
|
|
|
+ if themesArray.count == 8 {
|
|
|
+ guard let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMPageDisplayThemeCollectionViewItem"), for: indexPath) as? KMPageDisplayThemeCollectionViewItem else {
|
|
|
+ return NSCollectionViewItem()
|
|
|
+ }
|
|
|
+
|
|
|
+ item.themesCollectionCellItem(item: indexPath.item, itemData: themesArray)
|
|
|
+ item.itemCallBack = { [weak self] customItem in
|
|
|
+ guard let self = self else { return }
|
|
|
+
|
|
|
+ self.themesArray.remove(at: customItem)
|
|
|
+ self.pdfView.setPageBackgroundColorWith(self.themesArray[0], viewMode: KMPDFViewMode(rawValue: 0)!)
|
|
|
+ self.reloadData()
|
|
|
+
|
|
|
+ let data = NSKeyedArchiver.archivedData(withRootObject: self.themesArray)
|
|
|
+ UserDefaults.standard.set(data, forKey: "kKMPDFViewModeThemesArray")
|
|
|
+ UserDefaults.standard.synchronize()
|
|
|
+ }
|
|
|
+
|
|
|
+// if !IAPProductsManager.defaultManager.isAvailableAllFunction {
|
|
|
+// item.vipImageView.isHidden = indexPath.item == 0 ? true : false
|
|
|
+// } else {
|
|
|
+// item.vipImageView.isHidden = true
|
|
|
+// }
|
|
|
+
|
|
|
+ return item
|
|
|
+ } else {
|
|
|
+ if indexPath.item == self.themesArray.count {
|
|
|
+ guard let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMPageDisplayCustomThemesCollectionViewItem"), for: indexPath) as? KMPageDisplayCustomThemesCollectionViewItem else {
|
|
|
+ return NSCollectionViewItem()
|
|
|
+ }
|
|
|
+
|
|
|
+ item.themesCustomCollectionCellItem(indexPath.item)
|
|
|
+ item.customItemActionCallback = { [weak self] customItem, color, isChangeColor in
|
|
|
+ guard let self = self else { return }
|
|
|
+
|
|
|
+ if isChangeColor {
|
|
|
+ guard self.pdfView.activeAnnotation == nil else { return }
|
|
|
+ self.themesArray[self.clickInteger] = color
|
|
|
+ self.pdfView.setPageBackgroundColorWith(self.themesArray[self.clickInteger], viewMode: KMPDFViewMode(rawValue: UInt(self.clickInteger))!)
|
|
|
+ self.reloadData()
|
|
|
+ } else {
|
|
|
+ self.themesArray.append(color)
|
|
|
+ self.clickInteger = customItem
|
|
|
+ self.pdfView.setPageBackgroundColorWith(self.themesArray[customItem], viewMode: KMPDFViewMode(rawValue: UInt(customItem))!)
|
|
|
+ }
|
|
|
+
|
|
|
+ let data = NSKeyedArchiver.archivedData(withRootObject: self.themesArray)
|
|
|
+ UserDefaults.standard.set(data, forKey: "kKMPDFViewModeThemesArray")
|
|
|
+ UserDefaults.standard.synchronize()
|
|
|
+ }
|
|
|
+
|
|
|
+// if !IAPProductsManager.defaultManager.isAvailableAllFunction {
|
|
|
+// item.vipImageView.isHidden = false
|
|
|
+// } else {
|
|
|
+// item.vipImageView.isHidden = true
|
|
|
+// }
|
|
|
+
|
|
|
+ return item
|
|
|
+ } else {
|
|
|
+ guard let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMPageDisplayThemeCollectionViewItem"), for: indexPath) as? KMPageDisplayThemeCollectionViewItem else {
|
|
|
+ return NSCollectionViewItem()
|
|
|
+ }
|
|
|
+
|
|
|
+ item.themesCollectionCellItem(item: indexPath.item, itemData: themesArray)
|
|
|
+ item.itemCallBack = { [weak self] customItem in
|
|
|
+ guard let self = self else { return }
|
|
|
+
|
|
|
+ self.themesArray.remove(at: customItem)
|
|
|
+ self.pdfView.setPageBackgroundColorWith(self.themesArray[0], viewMode: KMPDFViewMode(rawValue: 0)!)
|
|
|
+ self.reloadData()
|
|
|
+
|
|
|
+ let data = NSKeyedArchiver.archivedData(withRootObject: self.themesArray)
|
|
|
+ UserDefaults.standard.set(data, forKey: "kKMPDFViewModeThemesArray")
|
|
|
+ UserDefaults.standard.synchronize()
|
|
|
+ }
|
|
|
+
|
|
|
+// if !IAPProductsManager.defaultManager.isAvailableAllFunction {
|
|
|
+// item.vipImageView.isHidden = indexPath.item == 0 ? true : false
|
|
|
+// } else {
|
|
|
+// item.vipImageView.isHidden = true
|
|
|
+// }
|
|
|
+
|
|
|
+ return item
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return NSCollectionViewItem()
|
|
|
+ }
|
|
|
+
|
|
|
+ func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
|
|
|
+ if themesArray.count == 8 {
|
|
|
+ return themesArray.count
|
|
|
+ } else {
|
|
|
+ return themesArray.count + 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {
|
|
|
+ let indexPathArr = Array(indexPaths)
|
|
|
+ for indexPath in indexPathArr {
|
|
|
+// if !IAPProductsManager.defaultManager.isAvailableAllFunction {
|
|
|
+// if indexPath.item > 0 {
|
|
|
+// KMPurchaseCompareWindowController.sharedInstance.showWindow(nil)
|
|
|
+// return
|
|
|
+// }
|
|
|
+// }
|
|
|
+ pdfView.setPageBackgroundColorWith(themesArray[indexPath.item], viewMode: KMPDFViewMode(rawValue: UInt(indexPath.item))!)
|
|
|
+ reloadData()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
|
|
|
+ return NSSize(width: 58, height: 64)
|
|
|
+ }
|
|
|
+
|
|
|
+}
|