1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027 |
- //
- // KMMeasureSideVC.swift
- // Cisdem PDFMaster
- //
- // Created by wanjun on 2024/7/15.
- //
- import Cocoa
- private enum KMMeasureType: Int {
- case line = 0
- case multilines
- case polygon
- case rectangle
- }
- @objcMembers
- class KMMeasureSideVC: NSViewController {
- // Preview
- @IBOutlet private weak var previewImageBox: NSBox!
- @IBOutlet private weak var previewImageView: NSImageView!
- // Type
- @IBOutlet private weak var typeView: NSView!
- @IBOutlet weak var typeBoxView: NSView!
- @IBOutlet private weak var typeSubView1: NSView!
- @IBOutlet private weak var typeButton1: NSButton!
- @IBOutlet private weak var typeSubView2: NSView!
- @IBOutlet private weak var typeButton2: NSButton!
- @IBOutlet private weak var typeSubView3: NSView!
- @IBOutlet private weak var typeButton3: NSButton!
- @IBOutlet private weak var typeSubView4: NSView!
- @IBOutlet private weak var typeButton4: NSButton!
- @IBOutlet private weak var verticalLine1: NSBox!
- @IBOutlet private weak var verticalLine2: NSBox!
- @IBOutlet private weak var verticalLine3: NSBox!
- @IBOutlet private weak var type_TopConstant: NSLayoutConstraint!
- // Border & Fill Color
- @IBOutlet private weak var fillColorView: NSView!
- @IBOutlet private weak var fillColorLabel: NSTextField!
- @IBOutlet private weak var fillColorPickerView: KMColorPickerView!
- @IBOutlet private weak var fillColorViewTopConstraint: NSLayoutConstraint!
- // Opacity
- @IBOutlet private weak var opacityView: NSView! // 透明度
- @IBOutlet private weak var opacityLabel: NSTextField!
- @IBOutlet private weak var opacitySlider: NSSlider!
- @IBOutlet private weak var opacityComboBox: KMComboBox!
- // Color
- @IBOutlet private weak var colorView: NSView! // 颜色
- @IBOutlet private weak var colorTitleLabel: NSTextField!
- @IBOutlet private weak var borderColorLabel: NSTextField!
- @IBOutlet private weak var borderColorBox: NSBox!
- @IBOutlet private weak var borderColorPickerView: KMColorPickerView!
-
- // Thickness
- @IBOutlet private weak var borderAndLineView: NSView! // 边框
- @IBOutlet private weak var borderLabel: NSTextField!
- @IBOutlet private weak var lineWidthSlider: NSSlider!
- @IBOutlet private weak var lineWidthComboBox: KMComboBox!
- // Line Style
- @IBOutlet private weak var lineStyle_View: NSView!
- @IBOutlet private weak var lineStyle_Label: NSTextField!
- @IBOutlet private weak var lineStyle_SolidButton: NSButton!
- @IBOutlet private weak var lineStyle_SolidImageView: NSImageView!
- @IBOutlet private weak var lineStyle_DottedButton: NSButton!
- @IBOutlet private weak var lineStyle_DottedImageView: NSImageView!
- @IBOutlet private weak var lineStyle_DashComBox: KMComboBox!
- @IBOutlet private weak var lineStyle_TopConstant: NSLayoutConstraint!
- // Start & End
- @IBOutlet private weak var startEnd_View: NSView!
- @IBOutlet private weak var startEnd_Label: NSTextField!
- @IBOutlet private weak var startEnd_StartPopUpButton: KMPopUpButton!
- @IBOutlet private weak var startEnd_EndPopUpButton: KMPopUpButton!
- @IBOutlet private weak var startEnd_TopConstant: NSLayoutConstraint!
- // Font
- @IBOutlet private weak var font_View: NSView!
- @IBOutlet private weak var font_Label: NSTextField!
- @IBOutlet private weak var font_PopUpButton: KMPopUpButton!
- @IBOutlet private weak var fontColorPickerView: KMColorPickerView!
- @IBOutlet private weak var font_StylePopUpButton: KMPopUpButton!
- @IBOutlet private weak var font_SizeComboBox: KMComboBox!
-
- var annotation: CPDFAnnotation?
- weak var pdfView: CPDFListView?
- var _annotationModel: CPDFAnnotationModel?
- var _annotations: [Any] = []
-
- private var measureType: KMMeasureType = .line
-
- deinit {
- NotificationCenter.default.removeObserver(self)
- borderColorPickerView.target = nil
- borderColorPickerView.action = nil
- fillColorPickerView.target = nil
- fillColorPickerView.action = nil
- fontColorPickerView.target = nil
- fontColorPickerView.action = nil
-
- NSColorPanel.shared.setTarget(nil)
- NSColorPanel.shared.setAction(nil)
- }
- override func viewDidLoad() {
- super.viewDidLoad()
- // Do view setup here.
-
- if annotations.count > 0 {
- if annotationType == .line {
- if pdfView?.toolMode == .measureToolMode {
- measureType = .line
- }
- } else if annotationType == .square {
- if pdfView?.toolMode == .measureToolMode {
- measureType = .rectangle
- }
- } else if annotationType == .polyGon {
- measureType = .polygon
- } else if annotationType == .polyLine {
- measureType = .multilines
- }
- } else {
- if annotationModel.annotationType == .line {
- measureType = .line
- } else if annotationModel.annotationType == .square {
- measureType = .rectangle
- } else if annotationModel.annotationType == .polyGon {
- measureType = .polygon
- } else if annotationModel.annotationType == .polyLine {
- measureType = .multilines
- }
- }
-
- languageLocalization()
- uiInitialize()
- layoutConstraintRefresh()
- updateViewColor()
- DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil)
- }
-
- @objc func themeChanged(notification: NSNotification) {
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [self] in
- updateViewColor()
- }
- }
-
- // MARK: Privately Methods
-
- private func languageLocalization() -> Void {
- colorTitleLabel.stringValue = NSLocalizedString("Color", comment: "")
- borderColorLabel.stringValue = NSLocalizedString("Line Color", comment: "")
- fillColorLabel.stringValue = NSLocalizedString("Fill Color", comment: "")
- opacityLabel.stringValue = NSLocalizedString("Opacity", comment: "")
- borderLabel.stringValue = NSLocalizedString("Line", comment: "")
- lineStyle_Label.stringValue = NSLocalizedString("Line Style", comment: "")
- startEnd_Label.stringValue = NSLocalizedString("Start & End", comment: "")
- font_Label.stringValue = NSLocalizedString("Font", comment: "")
- }
-
- private func uiInitialize() -> Void {
- borderColorPickerView.annotationType = .lineColors
- fillColorPickerView.annotationType = .lineFillColors
- borderColorPickerView.isCallColorPanelAction = true
- fillColorPickerView.isCallColorPanelAction = true
- fontColorPickerView.annotationType = .freeTextColors
- fontColorPickerView.isCallColorPanelAction = true
-
- self.typeView.isHidden = true
-
- borderColorLabel.textColor = KMAppearance.Layout.h0Color()
- borderColorLabel.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
- fillColorLabel.textColor = KMAppearance.Layout.h0Color()
- fillColorLabel.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
- opacityLabel.textColor = KMAppearance.Layout.h0Color()
- opacityLabel.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
- borderLabel.textColor = KMAppearance.Layout.h0Color()
- borderLabel.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
- lineStyle_Label.textColor = KMAppearance.Layout.h0Color()
- lineStyle_Label.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
- startEnd_Label.textColor = KMAppearance.Layout.h0Color()
- startEnd_Label.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
- font_Label.textColor = KMAppearance.Layout.h0Color()
- font_Label.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
-
- opacityComboBox.type = .none
- opacityComboBox.comboxRect = opacityComboBox.bounds
- lineWidthComboBox.type = .none
- lineWidthComboBox.comboxRect = lineWidthComboBox.bounds
- lineStyle_DashComBox.type = .none
- lineStyle_DashComBox.comboxRect = lineStyle_DashComBox.bounds
- font_PopUpButton.type = .arrowDown
- font_PopUpButton.removeAllItems()
-
- font_StylePopUpButton.type = .arrowDown
- font_StylePopUpButton.removeAllItems()
-
- font_SizeComboBox.type = .none
- font_SizeComboBox.comboxRect = font_SizeComboBox.bounds
-
- lineStyle_SolidImageView.image = NSImage(named: "KMImageNameLifeStyle")
- lineStyle_DottedImageView.image = NSImage(named: "KMImageNameLifeStyle2")
- lineStyle_DashComBox.isEnabled = false
- if annotationModel.measureDashPattern().count > 0 {
- lineStyle_DashComBox.stringValue = (annotationModel.measureDashPattern().first as! NSNumber).description
- } else {
- lineStyle_DashComBox.stringValue = "5"
- }
- annotationFontReload()
- if measureType == .line {
- previewImageView.image = NSImage(named: "KMImageNamePreviewMeasure")
-
- startEnd_StartPopUpButton.type = .arrowDown
- startEnd_StartPopUpButton.removeAllItems()
- startEnd_EndPopUpButton.type = .arrowDown
- startEnd_EndPopUpButton.removeAllItems()
-
- let startMenu = NSMenu()
- _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 0)
- _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 1)
- _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 2)
- _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 3)
- _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 4)
- _ = startMenu.addItem(withTitle: "", action: #selector(startMenuItemAction(_:)), target: self, tag: 5)
- startEnd_StartPopUpButton.menu = startMenu
- let endMenu = NSMenu()
- _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 0)
- _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 1)
- _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 2)
- _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 3)
- _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 4)
- _ = endMenu.addItem(withTitle: "", action: #selector(endMenuItemAction(_:)), target: self, tag: 5)
- startEnd_EndPopUpButton.menu = endMenu
- let startPopMenu = startEnd_StartPopUpButton.menu
- let endPopMenu = startEnd_EndPopUpButton.menu
- let startLineStyle = annotationModel.measureStartLineStyle()
- let endLineStyle = annotationModel.measureEndLineStyle()
- let startArr = self.startLineStyle()
- let endArr = self.endLineStyle()
- for i in 0..<startArr.count {
- let item = startPopMenu!.item(withTag: i)
- item?.image = startArr[i]
- }
- for i in 0..<endArr.count {
- let item = endPopMenu!.item(withTag: i)
- item?.image = endArr[i]
- }
- startEnd_StartPopUpButton.selectItem(at: startLineStyle.rawValue)
- startEnd_EndPopUpButton.selectItem(at: endLineStyle.rawValue)
- thicknessViewRefresh()
- } else if measureType == .multilines {
- previewImageView.image = NSImage(named: "KMImageNamePreviewPolyline")
- thicknessViewRefresh()
- } else if measureType == .polygon {
- previewImageView.image = NSImage(named: "KMImageNamePreviewPolygon")
- lineColorViewRefresh()
- thicknessViewRefresh()
- } else if measureType == .rectangle {
- previewImageView.image = NSImage(named: "KMImageNamePreviewMeasureSquare")
- lineColorViewRefresh()
- }
-
- fontColorPickerView.color = annotationModel.measureFontColor()
- font_SizeComboBox.stringValue = String(format: "%.f pt", annotationModel.measureFontSize())
- borderColorViewRefresh()
- typeViewRefresh()
- opacityViewRefresh()
- lineStyleViewRefresh()
- }
-
- private func typeViewRefresh() -> Void {
- verticalLine1.isHidden = false
- verticalLine2.isHidden = false
- verticalLine3.isHidden = false
- typeSubView1.backgroundColor(.clear)
- typeSubView2.backgroundColor(.clear)
- typeSubView3.backgroundColor(.clear)
- typeSubView4.backgroundColor(.clear)
- typeButton1.image = NSImage(named: "ImageNameToolbarMeasureLine")
- typeButton2.image = NSImage(named: "ImageNameToolbarPolyline")
- typeButton3.image = NSImage(named: "ImageNameToolbarPolygon")
- typeButton4.image = NSImage(named: "ImageNameToolbarMeasureSquare")
- // typeButton1.isEnabled = false
- // typeButton2.isEnabled = false
- // typeButton3.isEnabled = false
- // typeButton4.isEnabled = false
- if measureType == .line {
- verticalLine1.isHidden = true
- typeSubView1.backgroundColor(NSColor.km_init(hex: "#477EDE", alpha: 0.1))
- typeButton1.isEnabled = true
- } else if measureType == .multilines {
- verticalLine1.isHidden = true
- verticalLine2.isHidden = true
- typeSubView2.backgroundColor(NSColor.km_init(hex: "#477EDE", alpha: 0.1))
- typeButton2.isEnabled = true
- } else if measureType == .polygon {
- verticalLine2.isHidden = true
- verticalLine3.isHidden = true
- typeSubView3.backgroundColor(NSColor.km_init(hex: "#477EDE", alpha: 0.1))
- typeButton3.isEnabled = false
- } else if measureType == .rectangle {
- verticalLine3.isHidden = true
- typeSubView4.backgroundColor(NSColor.km_init(hex: "#477EDE", alpha: 0.1))
- }
- }
-
- private func borderColorViewRefresh() -> Void {
- borderColorPickerView.color = annotationModel.measureBorderColor()
- }
-
- private func lineColorViewRefresh() -> Void {
- fillColorPickerView.color = annotationModel.measureLineColor()
- }
-
- private func fontColorViewRefresh() -> Void {
- fontColorPickerView.color = annotationModel.measureFontColor()
- }
-
- private func opacityViewRefresh() -> Void {
- opacitySlider.floatValue = Float(annotationModel.measureOpacity())
- opacitySlider.toolTip = "\(Int(Float(annotationModel.measureOpacity()) * 100))%"
- opacityComboBox.stringValue = "\(Int(Float(annotationModel.measureOpacity()) * 100))%"
- }
-
- private func thicknessViewRefresh() -> Void {
- lineWidthSlider.floatValue = Float(annotationModel.measureLineWidth())
- lineWidthSlider.toolTip = String(format: "%.1f", Float(annotationModel.measureLineWidth()))
- lineWidthComboBox.stringValue = String(format: "%.1f", Float(annotationModel.measureLineWidth()))
- }
-
- private func lineStyleViewRefresh() -> Void {
- if annotationModel.measureLineStyle() == .solid {
- lineStyle_SolidButton.image = NSImage(named: "KMImageNameCheckboxRadiSel")
- lineStyle_DottedButton.image = NSImage(named: "KMImageNameCheckboxRadi")
- lineStyle_DashComBox.isEnabled = false
- } else {
- lineStyle_SolidButton.image = NSImage(named: "KMImageNameCheckboxRadi")
- lineStyle_DottedButton.image = NSImage(named: "KMImageNameCheckboxRadiSel")
- lineStyle_DashComBox.isEnabled = true
- }
- }
-
- private func layoutConstraintRefresh() -> Void {
- colorView.isHidden = false
- fillColorView.isHidden = false
- opacityView.isHidden = false
- borderAndLineView.isHidden = false
- lineStyle_View.isHidden = false
- startEnd_View.isHidden = false
- font_View.isHidden = false
- if measureType == .line {
- fillColorView.isHidden = true
- } else if measureType == .multilines {
- fillColorView.isHidden = true
- startEnd_View.isHidden = true
- } else if measureType == .polygon {
- startEnd_View.isHidden = true
- } else if measureType == .rectangle {
- startEnd_View.isHidden = true
- }
- fillColorViewTopConstraint.constant = !fillColorView.isHidden ? 92.0 : 10.0
- lineStyle_TopConstant.constant = !lineStyle_View.isHidden ? 0.0 : -CGRectGetHeight(lineStyle_View.bounds)
- startEnd_TopConstant.constant = !startEnd_View.isHidden ? 0.0 : -CGRectGetHeight(startEnd_View.bounds)
- }
-
- private func setFontStyle(fontName: String, currentStyle style: String?) -> UInt {
- var selectIndex: UInt = 0
- let menu = NSMenu()
- let fontStyleNames = CPDFFont.fontNames(forFamilyName: fontName)
-
- for i in 0..<fontStyleNames.count {
- let styleName = fontStyleNames[i]
- if style == styleName {
- selectIndex = UInt(i)
- }
- let item = NSMenuItem()
- item.title = styleName
-
- menu.addItem(item)
- }
- if style == nil {
- selectIndex = 0
- }
- font_StylePopUpButton.menu = menu
- return selectIndex
- }
-
- private func annotationFontReload() {
- DispatchQueue.global(qos: .default).async { [weak self] in
- guard let self = self else { return }
- let fonts = CPDFFont.familyNames
- let menu = NSMenu()
- var selectedIndex = 0
-
- for (index, fontName) in fonts.enumerated() {
- if let font = NSFont(name: fontName, size: 12.0) {
- let attributedString = NSAttributedString(string: fontName, attributes: [.font: font])
- let item = NSMenuItem()
- item.attributedTitle = attributedString
- menu.addItem(item)
- if [.line, .polyGon, .polyLine, .square].contains(self.annotationType),
- let modelFontName = self.annotationModel.measureFontName(),
- modelFontName == fontName {
- selectedIndex = index
- }
- }
- }
-
- if [.line, .polyGon, .polyLine, .square].contains(self.annotationType),
- let data = self.annotationModel.measureFontName() {
- let freetextFont = NSFont(name: data, size: 16) ?? NSFont.systemFont(ofSize: 16)
- if let family = freetextFont.fontDescriptor.object(forKey: .family) as? String,
- let style = freetextFont.fontDescriptor.object(forKey: .face) as? String {
-
- DispatchQueue.main.async { [weak self] in
- guard let self = self else { return }
-
- self.font_PopUpButton.menu = menu
- self.font_PopUpButton.selectItem(at: selectedIndex)
-
- let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
- self.font_StylePopUpButton.selectItem(at: Int(selectedStyleIndex))
- }
- }
- }
- }
- }
-
- @IBAction private func colorPanelAction1(_ sender: NSButton) {
- annotationModel.setMeasureBorderColor(NSColorPanel.shared.color)
- borderColorViewRefresh()
- updateAnnotation()
- }
-
- @IBAction private func colorPanelAction2(_ sender: NSButton) {
- lineColorViewRefresh()
- annotationModel.setMeasureLineColor(NSColorPanel.shared.color)
- updateAnnotation()
- }
-
- @IBAction private func colorPanelAction3(_ sender: NSButton) {
- fontColorViewRefresh()
- annotationModel.setMeasureFontColor(NSColorPanel.shared.color)
- updateAnnotation()
- }
-
- func updateViewColor() {
- self.typeBoxView.wantsLayer = true
- self.typeBoxView.layer?.borderWidth = 1
-
- if KMAppearance.isDarkMode() {
- let darkColor = NSColor(red: 57/255.0, green: 60/255.0, blue: 62/255.0, alpha: 1.0).cgColor
- let borderColor = NSColor(red: 86/255.0, green: 88/255.0, blue: 90/255.0, alpha: 1.0).cgColor
-
- setViewColor(font_PopUpButton, darkColor, borderColor)
- setViewColor(font_SizeComboBox, darkColor, borderColor)
- setViewColor(font_StylePopUpButton, darkColor, borderColor)
- setViewColor(lineWidthComboBox, darkColor, borderColor)
- setViewColor(opacityComboBox, darkColor, borderColor)
- setViewColor(opacityComboBox, darkColor, borderColor)
- setViewColor(lineStyle_DashComBox, darkColor, borderColor)
- self.typeBoxView.layer?.borderColor = NSColor(hex: "#424345").cgColor
- } else {
- let lightColor = NSColor.white.cgColor
- let borderColor = NSColor(red: 218/255.0, green: 219/255.0, blue: 222/255.0, alpha: 1.0).cgColor
-
- setViewColor(font_PopUpButton, lightColor, borderColor)
- setViewColor(font_SizeComboBox, lightColor, borderColor)
- setViewColor(font_StylePopUpButton, lightColor, borderColor)
- setViewColor(lineWidthComboBox, lightColor, borderColor)
- setViewColor(opacityComboBox, lightColor, borderColor)
- setViewColor(opacityComboBox, lightColor, borderColor)
- setViewColor(lineStyle_DashComBox, lightColor, borderColor)
-
- self.typeBoxView.layer?.borderColor = NSColor(hex: "#E2E3E6").cgColor
- }
- }
-
- func setViewColor(_ view: NSView, _ backgroundColor: CGColor, _ borderColor: CGColor) {
- view.wantsLayer = true
- view.layer?.backgroundColor = backgroundColor
- view.layer?.borderColor = borderColor
- }
-
- private func updateAnnotation() {
- if annotationModel.annotation != nil {
- for tAnnotation in annotations {
- pdfView?.setNeedsDisplayAnnotationViewFor((tAnnotation as AnyObject).page)
- }
- }
- }
-
- private func startLineStyle() -> [NSImage] {
- let size = NSSize(width: 100.0, height: 12.0)
- let image1 = NSImage.image(with: size) { rect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0-4, y: 6.0))
- path.line(to: NSPoint(x: 6.0, y: 6.0))
- path.lineWidth = 2.0
- NSColor.labelColor.setStroke()
- path.stroke()
- return true
- }
-
- let image2 = NSImage.image(with: size) { dstRect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0-4, y: 6.0))
- path.line(to: NSPoint(x: 12.0, y: 6.0))
- path.appendRect(NSRect(x: 6.0, y: 3.0, width: 6.0, height: 6.0))
- path.lineWidth = 2.0
- NSColor.labelColor.setStroke()
- path.stroke()
- return true
- }
-
- let image3 = NSImage.image(with: size) { dstRect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0-4, y: 6.0))
- path.line(to: NSPoint(x: 12.0, y: 6.0))
- path.appendOval(in: NSRect(x: 6.0, y: 3.0, width: 6.0, height: 6.0))
- path.lineWidth = 2.0
- NSColor.labelColor.setStroke()
- path.stroke()
- return true
- }
-
- let image4 = NSImage.image(with: size) { dstRect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0-4, y: 6.0))
- path.line(to: NSPoint(x: 14.0, y: 6.0))
- path.move(to: NSPoint(x: 14.0, y: 6.0))
- path.line(to: NSPoint(x: 10.0, y: 10.0))
- path.line(to: NSPoint(x: 6.0, y: 6.0))
- path.line(to: NSPoint(x: 10.0, y: 2.0))
- path.close()
- NSColor.labelColor.setStroke()
- path.lineWidth = 2.0
- path.stroke()
- return true
- }
-
- let image5 = NSImage.image(with: size) { dstRect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0-4, y: 6.0))
- path.line(to: NSPoint(x: 6.0, y: 6.0))
- path.move(to: NSPoint(x: 15.0, y: 3.0))
- path.line(to: NSPoint(x: 6.0, y: 6.0))
- path.line(to: NSPoint(x: 15.0, y: 9.0))
- path.lineWidth = 2.0
- NSColor.labelColor.setStroke()
- path.stroke()
- return true
- }
-
- let image6 = NSImage.image(with: size) { dstRect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0-4, y: 6.0))
- path.line(to: NSPoint(x: 6.0, y: 6.0))
- path.move(to: NSPoint(x: 15.0, y: 3.0))
- path.line(to: NSPoint(x: 6.0, y: 6.0))
- path.line(to: NSPoint(x: 15.0, y: 9.0))
- path.close()
- path.lineWidth = 2.0
- NSColor.labelColor.setStroke()
- path.stroke()
- return true
- }
-
- return [image1, image5, image6, image2, image3, image4]
- }
-
- private func endLineStyle() -> [NSImage] {
- let size = NSSize(width: 100.0, height: 12.0)
- let image1 = NSImage.image(with: size) { rect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 6.0, y: 6.0))
- path.line(to: NSPoint(x: 93.0-4, y: 6.0))
- path.lineWidth = 2.0
- NSColor.labelColor.setStroke()
- path.stroke()
- return true
- }
-
- let image2 = NSImage.image(with: size) { rect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 6.0, y: 6.0))
- path.line(to: NSPoint(x: 87.0-4, y: 6.0))
- path.appendRect(NSRect(x: 87.0-4, y: 3.0, width: 6.0, height: 6.0))
- path.lineWidth = 2.0
- NSColor.labelColor.setStroke()
- path.stroke()
- return true
- }
- let image3 = NSImage.image(with: size) { rect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 6.0, y: 6.0))
- path.line(to: NSPoint(x: 87.0-4, y: 6.0))
- path.appendOval(in: NSRect(x: 87.0-4, y: 3.0, width: 6.0, height: 6.0))
- path.lineWidth = 2.0
- NSColor.labelColor.setStroke()
- path.stroke()
- return true
- }
- let image4 = NSImage.image(with: size) { rect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 6.0, y: 6.0))
- path.line(to: NSPoint(x: 87.0-4, y: 6.0))
- path.move(to: NSPoint(x: 87.0-4, y: 6.0))
- path.line(to: NSPoint(x: 91.0-4, y: 10.0))
- path.line(to: NSPoint(x: 95.0-4, y: 6.0))
- path.line(to: NSPoint(x: 91.0-4, y: 2.0))
- path.close()
- NSColor.labelColor.setStroke()
- path.lineWidth = 2.0
- path.stroke()
- return true
- }
- let image5 = NSImage.image(with: size) { rect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 6.0, y: 6.0))
- path.line(to: NSPoint(x: 93.0-4, y: 6.0))
- path.move(to: NSPoint(x: 84.0-4, y: 3.0))
- path.line(to: NSPoint(x: 93.0-4, y: 6.0))
- path.line(to: NSPoint(x: 84.0-4, y: 9.0))
- path.lineWidth = 2.0
- NSColor.labelColor.setStroke()
- path.stroke()
- return true
- }
- let image6 = NSImage.image(with: size) { rect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 6.0, y: 6.0))
- path.line(to: NSPoint(x: 93.0-4, y: 6.0))
- path.move(to: NSPoint(x: 84.0-4, y: 3.0))
- path.line(to: NSPoint(x: 93.0-4, y: 6.0))
- path.line(to: NSPoint(x: 84.0-4, y: 9.0))
- path.close()
- path.lineWidth = 2.0
- NSColor.labelColor.setStroke()
- path.stroke()
- return true
- }
- return [image1, image5, image6, image2, image3, image4]
- }
-
- private func isNumericUsingNSRegularExpression(_ input: String) -> Bool {
- let pattern = "^[0-9]+$"
- do {
- let regex = try NSRegularExpression(pattern: pattern)
- let matches = regex.matches(in: input, range: NSRange(location: 0, length: input.utf16.count))
- return matches.count > 0
- } catch {
- print("Invalid regex pattern")
- return false
- }
- }
- // MARK: Publicly Methods
-
-
- // MARK: Action
-
- @IBAction func typeButtonAction(_ sender: NSButton) {
- }
-
- @IBAction func borderColorPickerViewAction(_ sender: Any) {
- var fillColor = NSColor.clear
- var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
- if let borderColor = borderColorPickerView.color {
- borderColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
- let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
- fillColor = color
- }
-
- annotationModel.setMeasureBorderColor(fillColor)
- annotationModel.setMeasureOpacity(opacity)
- opacityViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func fillColorPickerViewAction(_ sender: Any) {
- var fillColor = NSColor.clear
- var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
- if let borderColor = fillColorPickerView.color {
- borderColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
- let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
- fillColor = color
- }
-
- if opacity == 0 {
- annotationModel.setMeasureLineColor(nil)
- } else {
- annotationModel.setMeasureLineColor(fillColor)
- }
- opacityViewRefresh()
- lineColorViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func fontColorPickerViewAction(_ sender: Any) {
- var fillColor = NSColor.clear
- var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
- if let borderColor = fontColorPickerView.color {
- borderColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
- let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
- fillColor = color
- }
- fontColorViewRefresh()
- annotationModel.setMeasureFontColor(fillColor)
- updateAnnotation()
- }
-
- @IBAction func customColorAction(_ sender: NSButton) {
- NSColorPanel.shared.setAction(nil)
- NSColorPanel.shared.setTarget(nil)
-
- NSColorPanel.shared.setTarget(self)
- NSColorPanel.shared.showsAlpha = true
- if sender.tag == 0 {
- NSColorPanel.shared.setAction(#selector(colorPanelAction1(_:)))
- } else if sender.tag == 1 {
- NSColorPanel.shared.setAction(#selector(colorPanelAction2(_:)))
- } else if sender.tag == 2 {
- NSColorPanel.shared.setAction(#selector(colorPanelAction3(_:)))
- }
- NSColorPanel.shared.orderFront(nil)
- }
-
- @IBAction func opacitySliderAction(_ sender: Any) {
- var opcity = CGFloat(opacitySlider.floatValue)
- if opcity == 0 {
- opcity = 0.0001
- }
- annotationModel.setMeasureOpacity(opcity)
- opacityViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func opacityComboBoxAction(_ sender: Any) {
- opacitySlider.floatValue = Float(opacityComboBox.floatValue / 100)
- var opcity = CGFloat(opacitySlider.floatValue)
- if opcity == 0 {
- opcity = 0.0001
- }
- annotationModel.setMeasureOpacity(opcity)
- opacityViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func thicknessSliderAction(_ sender: Any) {
- var thickness = CGFloat(lineWidthSlider.floatValue)
- annotationModel.setMeasureLineWidth(thickness)
- thicknessViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func thicknessComboBoxAction(_ sender: Any) {
- lineWidthSlider.floatValue = Float(lineWidthComboBox.floatValue)
- let thickness = CGFloat(lineWidthSlider.floatValue)
-
- annotationModel.setMeasureLineWidth(thickness)
- thicknessViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func lineStyleButtonAction(_ sender: NSButton) {
- if sender.tag == 0 {
- annotationModel.setMeasureLineStyle(.solid)
- } else {
- annotationModel.setMeasureLineStyle(.dashed)
- annotation?.setDashPattern(annotationModel.measureDashPattern())
- }
- lineStyleViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func startMenuItemAction(_ sender: NSMenuItem) {
- let startType: CPDFLineStyle = (CPDFLineStyle(rawValue: sender.tag) ?? CPDFLineStyle(rawValue: 0))!
- annotationModel.setMeasureStart(startType)
- updateAnnotation()
- }
-
- @IBAction func endMenuItemAction(_ sender: NSMenuItem) {
- let endType: CPDFLineStyle = (CPDFLineStyle(rawValue: sender.tag) ?? CPDFLineStyle(rawValue: 0))!
- annotationModel.setMeasureEnd(endType)
- updateAnnotation()
- }
-
- @IBAction func fontButtonAction(_ sender: NSButton) {
- let selectItem = font_PopUpButton.selectedItem
- guard let selectItem = selectItem else { return }
-
- let resultAtt = NSMutableAttributedString(attributedString: selectItem.attributedTitle!)
- let familyString = resultAtt.string
- let styleString = font_StylePopUpButton.selectedItem?.title ?? ""
- let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [.family: familyString, .face: styleString as Any])
- let fontSizeString = font_SizeComboBox.stringValue.replacingOccurrences(of: " pt", with: "")
- let fontModel = KMFontModel(fontName: familyString, fontWeight: styleString, fontSize: fontSizeString.stringToCGFloat(), fontColor: fontColorPickerView.color ?? .black, fontAlignment: .left, annotationType: annotationModel.annotationType)
-
- let fontWindowController = KMAnnotationFontWindowController.initWindowController(fontModel)
- fontWindowController.isHidenAlignmentLabel = true
- let window = fontWindowController.window
- fontWindowController.callback = { [weak self] model in
- self?.fontColorPickerView.color = model.fontColor
-
- DispatchQueue.global(qos: .default).async { [self]
- let fonts = CPDFFont.familyNames
- let menu = NSMenu()
- var selectedIndex = 0
-
- for (index, fontName) in fonts.enumerated() {
- if let font = NSFont(name: fontName, size: 12.0) {
- let attributedString = NSAttributedString(string: fontName, attributes: [.font: font])
- let item = NSMenuItem()
- item.attributedTitle = attributedString
- menu.addItem(item)
-
- if let family = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
- let style = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
- if model.fontName == family {
- selectedIndex = index
- }
- }
- }
- }
- DispatchQueue.main.async {
- self?.font_PopUpButton.menu = menu
- self?.font_PopUpButton.selectItem(at: selectedIndex)
- }
- }
- let selectedStyleIndex = self?.setFontStyle(fontName: model.fontName, currentStyle: model.fontWeight) ?? 0
- self?.font_StylePopUpButton.selectItem(at: Int(selectedStyleIndex))
- self?.font_SizeComboBox.stringValue = String(format: "%.f pt", model.fontSize)
-
- self?.annotationModel.setMeasureFontName(model.fontName)
- self?.annotationModel.setMeasureFontSize(model.fontSize)
- self?.annotationModel.setMeasureFontColor(model.fontColor)
- if self?.annotationModel.annotations != nil {
- self?.updateAnnotation()
- }
- }
- window?.orderFront(sender)
- }
-
- @IBAction func fontPopUpButtonAction(_ sender: NSPopUpButton) {
- guard let selectedItem = font_PopUpButton.selectedItem else { return }
-
- let resultAtt = NSMutableAttributedString(attributedString: selectedItem.attributedTitle!)
- let familyString = resultAtt.string
- let selectIndex = setFontStyle(fontName: familyString, currentStyle: nil)
- guard let styleString = font_StylePopUpButton.selectedItem?.title else { return }
-
- font_StylePopUpButton.selectItem(at: Int(selectIndex))
-
- for tAnnotation in annotations {
- if tAnnotation is CPDFLineAnnotation {
- let newAnnotation = (tAnnotation as! CPDFLineAnnotation)
- newAnnotation.cFont = CPDFFont(familyName: familyString, fontStyle: styleString)
- } else if tAnnotation is CPDFPolygonAnnotation {
- let newAnnotation = (tAnnotation as! CPDFPolygonAnnotation)
- newAnnotation.cFont = CPDFFont(familyName: familyString, fontStyle: styleString)
- } else if tAnnotation is CPDFPolylineAnnotation {
- let newAnnotation = (tAnnotation as! CPDFPolylineAnnotation)
- newAnnotation.cFont = CPDFFont(familyName: familyString, fontStyle: styleString)
- }
- }
- self.annotationModel.setMeasureFontName(familyString)
- if annotations.count > 0 {
- pdfView?.setNeedsDisplay(annotation)
- }
- }
-
- @IBAction func fontSizeComboBoxAction(_ sender: NSComboBox) {
- if annotationModel.annotations != nil {
- for tAnnotation in annotations {
- if tAnnotation is CPDFLineAnnotation {
- let newAnnotation = (tAnnotation as! CPDFLineAnnotation)
- newAnnotation.fontSize = CGFloat(font_SizeComboBox.floatValue)
- } else if tAnnotation is CPDFPolygonAnnotation {
- let newAnnotation = (tAnnotation as! CPDFPolygonAnnotation)
- newAnnotation.fontSize = CGFloat(font_SizeComboBox.floatValue)
- } else if tAnnotation is CPDFPolylineAnnotation {
- let newAnnotation = (tAnnotation as! CPDFPolylineAnnotation)
- newAnnotation.fontSize = CGFloat(font_SizeComboBox.floatValue)
- }
- }
- } else {
- if annotationType == .line || annotationType == .polyGon || annotationType == .polyLine {
- if let data = annotationModel.measureFontName() {
- let font = NSFont(name: data, size: annotationModel.measureFontSize()) ?? NSFont.systemFont(ofSize: 16)
- let newFont = NSFont(name: font.fontName, size: CGFloat(font_SizeComboBox.floatValue))
- if let newFont = newFont {
- annotationModel.setMeasureFontName(newFont.fontName)
- annotationModel.setMeasureFontSize(newFont.pointSize)
- }
- }
- }
- }
- updateAnnotation()
- }
-
- //字重 NSFontWeight
- @IBAction func fontStylePopUpButtonAction(_ sender: NSPopUpButton) {
- if let styleString = font_StylePopUpButton.selectedItem?.title {
- if annotationModel.annotations != nil {
- for tAnnotation in self.annotations {
- if tAnnotation is CPDFLineAnnotation {
- let newAnnotation = (tAnnotation as! CPDFLineAnnotation)
- newAnnotation.cFont = CPDFFont(familyName: newAnnotation.cFont.familyName, fontStyle: styleString)
- } else if tAnnotation is CPDFPolygonAnnotation {
- let newAnnotation = (tAnnotation as! CPDFPolygonAnnotation)
- newAnnotation.cFont = CPDFFont(familyName: newAnnotation.cFont.familyName, fontStyle: styleString)
- } else if tAnnotation is CPDFPolylineAnnotation {
- let newAnnotation = (tAnnotation as! CPDFPolylineAnnotation)
- newAnnotation.cFont = CPDFFont(familyName: newAnnotation.cFont.familyName, fontStyle: styleString)
- }
- }
- } else {
- if annotationType == .line || annotationType == .polyGon || annotationType == .polyLine {
- if let data = annotationModel.measureFontName() {
- let font = NSFont(name: data, size: annotationModel.measureFontSize()) ?? NSFont.systemFont(ofSize: 16)
- if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? Int,
- let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
-
- let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
- if let newFont = NSFont(descriptor: attributeFontDescriptor, size: CGFloat(fontSize)) {
- annotationModel.setMeasureFontName(newFont.fontName)
- annotationModel.setMeasureFontSize(newFont.pointSize)
- }
- }
- }
- }
- }
- }
- updateAnnotation()
- }
- @IBAction func lineDashComboBoxAction(_ sender: NSComboBox) {
- let number = NSNumber(value: lineStyle_DashComBox.floatValue)
- var lineDashPattern: [Any] = annotationModel.measureDashPattern()
- let array: [NSNumber]
- if annotationModel.measureDashPattern() is [NSNumber] {
- if lineDashPattern.isEmpty {
- array = [number]
- } else {
- lineDashPattern[0] = number
- array = lineDashPattern as! [NSNumber]
- }
- } else {
- array = [number]
- }
-
- annotationModel.setMeasureDashPattern(array)
- updateAnnotation()
- }
-
- // MARK: Set & Get
-
- var annotations: [Any] {
- set {
- _annotations = newValue
-
- self.annotation = (newValue.first as? CPDFAnnotation)
- }
- get {
- return _annotations
- }
- }
-
- var annotationModel: CPDFAnnotationModel {
- get {
- return _annotationModel!
- }
- set {
- _annotationModel = newValue
- if _annotationModel?.annotations != nil {
- if annotationModel.annotations.count > 0 {
- annotations = _annotationModel?.annotations as! [CPDFAnnotation]
- }
- }
- }
- }
-
- var annotationType: CAnnotationType {
- get {
- if annotations.count > 0 {
- if let ann = annotation?.isKind(of: CPDFLineAnnotation.self), ann {
- if (annotation as! CPDFLineAnnotation).isMeasure {
- return .line
- }
- } else if let ann = annotation?.isKind(of: CPDFPolygonAnnotation.self), ann {
- if pdfView?.annotationType == .square {
- return .square
- }
- return .polyGon
- } else if let ann = annotation?.isKind(of: CPDFPolylineAnnotation.self), ann {
- return .polyLine
- }
- } else {
- return annotationModel.annotationType
- }
- return .unkown
- }
- }
-
- }
|