123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886 |
- //
- // 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 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 border_FillView: NSView!
- @IBOutlet private weak var border_Label: NSTextField!
- @IBOutlet private weak var borderColor_View: NSView!
- @IBOutlet private weak var borderColor_Button: NSButton!
- @IBOutlet private weak var borderColor_TopConstant: NSLayoutConstraint!
- // Line Color
- @IBOutlet private weak var lineColor_View: NSView!
- @IBOutlet private weak var lineColor_Label: NSTextField!
- @IBOutlet private weak var lineColor_ColorView: NSView!
- @IBOutlet private weak var lineColor_ColorButton: NSButton!
- @IBOutlet private weak var lineColor_TopConstant: NSLayoutConstraint!
- // Opacity
- @IBOutlet private weak var opacity_View: NSView!
- @IBOutlet private weak var opacity_Label: NSTextField!
- @IBOutlet private weak var opacity_Slider: NSSlider!
- @IBOutlet private weak var opacity_ComboBox: KMComboBox!
- @IBOutlet private weak var opacity_TopConstant: NSLayoutConstraint!
- // Thickness
- @IBOutlet private weak var thickness_View: NSView!
- @IBOutlet private weak var thickness_Label: NSTextField!
- @IBOutlet private weak var thickness_Slider: NSSlider!
- @IBOutlet private weak var thickness_ComboBox: KMComboBox!
- @IBOutlet private weak var thickness_TopConstant: NSLayoutConstraint!
- // 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_TextField: NSTextField!
- @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 font_ColorView: NSView!
- @IBOutlet private weak var font_ColorButton: NSButton!
- @IBOutlet private weak var font_StylePopUpButton: KMPopUpButton!
- @IBOutlet private weak var font_SizeComboBox: KMComboBox!
- @IBOutlet private weak var font_TopConstant: NSLayoutConstraint!
-
- var annotation: CPDFAnnotation?
- weak var pdfView: CPDFListView?
- var _annotationModel: CPDFAnnotationModel?
- var _annotations: [Any] = []
-
- private var measureType: KMMeasureType = .line
-
- deinit {
- NotificationCenter.default.removeObserver(self)
- }
- override func viewDidLoad() {
- super.viewDidLoad()
- // Do view setup here.
-
- 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
- }
-
- languageLocalization()
- uiInitialize()
- layoutConstraintRefresh()
-
- NotificationCenter.default.addObserver(self, selector: #selector(textFieldDidEndEditingNotification(_:)), name: NSControl.textDidEndEditingNotification, object: lineStyle_TextField)
- }
-
- // MARK: Privately Methods
-
- private func languageLocalization() -> Void {
- if measureType == .polygon {
- border_Label.stringValue = NSLocalizedString("Fill", comment: "")
- } else {
- border_Label.stringValue = NSLocalizedString("Border", comment: "")
- }
- lineColor_Label.stringValue = NSLocalizedString("Line Color", comment: "")
- opacity_Label.stringValue = NSLocalizedString("Opacity", comment: "")
- thickness_Label.stringValue = NSLocalizedString("Thickness", 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 {
- border_Label.textColor = KMAppearance.Layout.h0Color()
- border_Label.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
- lineColor_Label.textColor = KMAppearance.Layout.h0Color()
- lineColor_Label.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
- opacity_Label.textColor = KMAppearance.Layout.h0Color()
- opacity_Label.font = NSFont(descriptor: NSFontDescriptor(name: "Segoe UI", size: 14.0).withSymbolicTraits(.bold), size: 14.0) ?? NSFont(name: "Segoe UI", size: 14.0)
- thickness_Label.textColor = KMAppearance.Layout.h0Color()
- thickness_Label.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)
-
- opacity_ComboBox.type = .none
- opacity_ComboBox.comboxRect = opacity_ComboBox.bounds
- thickness_ComboBox.type = .none
- thickness_ComboBox.comboxRect = thickness_ComboBox.bounds
- font_PopUpButton.type = .arrowDown
- font_PopUpButton.removeAllItems()
-
- font_PopUpButton.type = .arrowDown
- font_PopUpButton.removeAllItems()
-
- font_SizeComboBox.type = .none
-
- lineStyle_SolidImageView.image = NSImage(named: "KMImageNameLifeStyle")
- lineStyle_DottedImageView.image = NSImage(named: "KMImageNameLifeStyle2")
- lineStyle_TextField.isEnabled = false
- if annotationModel.dashPattern().count > 0 {
- lineStyle_TextField.stringValue = (annotationModel.dashPattern().first as! NSNumber).description
- } else {
- lineStyle_TextField.stringValue = "5"
- }
- annotationFontReload()
- if measureType == .line {
- previewImageView.image = NSImage(named: "ImageNameToolbarMeasureLine")
-
- 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.startLineStyle()
- let endLineStyle = annotationModel.endLineStyle()
- 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]
- }
- if let line = annotation?.isKind(of: CPDFLineAnnotation.self), line {
- startEnd_StartPopUpButton.selectItem(at: (annotation as! CPDFLineAnnotation).startLineStyle.rawValue)
- startEnd_EndPopUpButton.selectItem(at: (annotation as! CPDFLineAnnotation).endLineStyle.rawValue)
- } else {
- startEnd_StartPopUpButton.selectItem(at: startLineStyle.rawValue)
- startEnd_EndPopUpButton.selectItem(at: endLineStyle.rawValue)
- }
- thicknessViewRefresh()
- } else if measureType == .multilines {
- previewImageView.image = NSImage(named: "ImageNameToolbarPolyline")
- thicknessViewRefresh()
- } else if measureType == .polygon {
- previewImageView.image = NSImage(named: "ImageNameToolbarPolygon")
- lineColorViewRefresh()
- thicknessViewRefresh()
- } else if measureType == .rectangle {
- previewImageView.image = NSImage(named: "ImageNameToolbarMeasureSquare")
- lineColorViewRefresh()
- }
-
- font_ColorView.backgroundColor(annotationModel.fontColor())
- font_SizeComboBox.stringValue = String(format: "%.f pt", annotationModel.fontSize())
- 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 {
- if measureType == .polygon || measureType == .rectangle {
- if annotation is CPDFPolygonAnnotation {
- let newAnnotation = (annotation as! CPDFPolygonAnnotation)
- borderColor_View.backgroundColor(newAnnotation.interiorColor)
- }
- } else {
- borderColor_View.backgroundColor(annotationModel.color())
- }
- }
-
- private func lineColorViewRefresh() -> Void {
- lineColor_ColorView.backgroundColor(annotationModel.color())
- }
-
- private func fontColorViewRefresh() -> Void {
- font_ColorView.backgroundColor(annotationModel.fontColor())
- }
-
- private func opacityViewRefresh() -> Void {
- opacity_Slider.floatValue = Float(annotationModel.opacity())
- opacity_Slider.toolTip = "\(Int(Float(annotationModel.opacity()) * 100))%"
- opacity_ComboBox.stringValue = "\(Int(Float(annotationModel.opacity()) * 100))%"
- }
-
- private func thicknessViewRefresh() -> Void {
- thickness_Slider.floatValue = Float(annotationModel.lineWidth())
- thickness_Slider.toolTip = "\(Int(Float(annotationModel.lineWidth())))"
- thickness_ComboBox.stringValue = "\(Int(Float(annotationModel.lineWidth())))"
- }
-
- private func lineStyleViewRefresh() -> Void {
- if annotationModel.style() == .solid {
- lineStyle_SolidButton.image = NSImage(named: "KMImageNameCheckboxRadiSel")
- lineStyle_DottedButton.image = NSImage(named: "KMImageNameCheckboxRadi")
- lineStyle_TextField.isEnabled = false
- } else {
- lineStyle_SolidButton.image = NSImage(named: "KMImageNameCheckboxRadi")
- lineStyle_DottedButton.image = NSImage(named: "KMImageNameCheckboxRadiSel")
- lineStyle_TextField.isEnabled = true
- }
- }
-
- private func layoutConstraintRefresh() -> Void {
- border_FillView.isHidden = false
- lineColor_View.isHidden = false
- opacity_View.isHidden = false
- thickness_View.isHidden = false
- lineStyle_View.isHidden = false
- startEnd_View.isHidden = false
- font_View.isHidden = false
- if measureType == .line {
- lineColor_View.isHidden = true
- } else if measureType == .multilines {
- lineColor_View.isHidden = true
- startEnd_View.isHidden = true
- } else if measureType == .polygon {
- startEnd_View.isHidden = true
- } else if measureType == .rectangle {
- thickness_View.isHidden = true
- startEnd_View.isHidden = true
- }
- borderColor_TopConstant.constant = !border_FillView.isHidden ? 10.0 : -CGRectGetHeight(border_FillView.bounds)
- lineColor_TopConstant.constant = !lineColor_View.isHidden ? 0.0 : -CGRectGetHeight(lineColor_View.bounds)
- opacity_TopConstant.constant = !opacity_View.isHidden ? 0.0 : -CGRectGetHeight(opacity_View.bounds)
- thickness_TopConstant.constant = !thickness_View.isHidden ? 0.0 : -CGRectGetHeight(thickness_View.bounds)
- lineStyle_TopConstant.constant = !lineStyle_View.isHidden ? 0.0 : -CGRectGetHeight(lineStyle_View.bounds)
- startEnd_TopConstant.constant = !startEnd_View.isHidden ? 0.0 : -CGRectGetHeight(startEnd_View.bounds)
- font_TopConstant.constant = !font_View.isHidden ? 0.0 : -CGRectGetHeight(font_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 attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: fontName, NSFontDescriptor.AttributeName.face: styleName])
- // let font = NSFont(descriptor: attributeFontDescriptor, size: 12.0)
- // let attrited = [NSAttributedString.Key.font: font]
- // let string = NSAttributedString(string: styleName, attributes: attrited as [NSAttributedString.Key : Any])
- //
- // let item = NSMenuItem()
- // item.attributedTitle = string
- 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.fontName(),
- modelFontName == font.fontName {
- selectedIndex = index
- }
- }
- }
-
- if [.line, .polyGon, .polyLine, .square].contains(self.annotationType),
- let data = self.annotationModel.fontName() {
- 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 }
-
- font_PopUpButton.menu = menu
- font_PopUpButton.selectItem(at: selectedIndex)
-
- let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
- font_StylePopUpButton.selectItem(at: Int(selectedStyleIndex))
- }
- }
- }
- }
- }
-
- @IBAction private func colorPanelAction1(_ sender: NSButton) {
- if measureType == .polygon || measureType == .rectangle {
- for tAnnotation in annotations {
- if tAnnotation is CPDFPolygonAnnotation {
- let newAnnotation = (tAnnotation as! CPDFPolygonAnnotation)
- newAnnotation.interiorColor = NSColorPanel.shared.color
- }
- }
- } else {
- annotationModel.setColor(NSColorPanel.shared.color)
- }
- borderColorViewRefresh()
- updateAnnotation()
- }
-
- @IBAction private func colorPanelAction2(_ sender: NSButton) {
- lineColorViewRefresh()
- annotationModel.setInteriorColor(NSColorPanel.shared.color)
-
- updateAnnotation()
- }
-
- @IBAction private func colorPanelAction3(_ sender: NSButton) {
- fontColorViewRefresh()
- annotationModel.setFontColor(NSColorPanel.shared.color)
- updateAnnotation()
- }
-
- 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: 109.0, height: 12.0)
- let image1 = NSImage.image(with: size) { rect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0, y: 6.0))
- path.line(to: NSPoint(x: 6.0, y: 6.0))
- path.lineWidth = 2.0
- NSColor.black.setStroke()
- path.stroke()
- return true
- }
-
- let image2 = NSImage.image(with: size) { dstRect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0, 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.black.setStroke()
- path.stroke()
- return true
- }
-
- let image3 = NSImage.image(with: size) { dstRect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0, 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.black.setStroke()
- path.stroke()
- return true
- }
-
- let image4 = NSImage.image(with: size) { dstRect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0, 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()
- 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, 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.black.setStroke()
- path.stroke()
- return true
- }
-
- let image6 = NSImage.image(with: size) { dstRect in
- let path = NSBezierPath()
- path.move(to: NSPoint(x: 93.0, 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.black.setStroke()
- path.stroke()
- return true
- }
-
- return [image1, image5, image6, image2, image3, image4]
- }
-
- private func endLineStyle() -> [NSImage] {
- let size = NSSize(width: 109.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, y: 6.0))
- path.lineWidth = 2.0
- NSColor.black.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, y: 6.0))
- path.appendRect(NSRect(x: 87.0, y: 3.0, width: 6.0, height: 6.0))
- path.lineWidth = 2.0
- NSColor.black.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, y: 6.0))
- path.appendOval(in: NSRect(x: 87.0, y: 3.0, width: 6.0, height: 6.0))
- path.lineWidth = 2.0
- NSColor.black.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, y: 6.0))
- path.move(to: NSPoint(x: 87.0, y: 6.0))
- path.line(to: NSPoint(x: 91.0, y: 10.0))
- path.line(to: NSPoint(x: 95.0, y: 6.0))
- path.line(to: NSPoint(x: 91.0, y: 2.0))
- path.close()
- 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, y: 6.0))
- path.move(to: NSPoint(x: 84.0, y: 3.0))
- path.line(to: NSPoint(x: 93.0, y: 6.0))
- path.line(to: NSPoint(x: 84.0, y: 9.0))
- path.lineWidth = 2.0
- NSColor.black.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, y: 6.0))
- path.move(to: NSPoint(x: 84.0, y: 3.0))
- path.line(to: NSPoint(x: 93.0, y: 6.0))
- path.line(to: NSPoint(x: 84.0, y: 9.0))
- path.close()
- path.lineWidth = 2.0
- NSColor.black.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 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(opacity_Slider.floatValue)
- if opcity == 0 {
- opcity = 0.0001
- }
- annotationModel.setOpacity(opcity)
- opacityViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func opacityComboBoxAction(_ sender: Any) {
- opacity_Slider.floatValue = Float(opacity_ComboBox.floatValue / 100)
- var opcity = CGFloat(opacity_Slider.floatValue)
- if opcity == 0 {
- opcity = 0.0001
- }
- annotationModel.setOpacity(opcity)
- opacityViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func thicknessSliderAction(_ sender: Any) {
- let thickness = CGFloat(thickness_Slider.floatValue)
- annotationModel.setLineWidth(thickness)
- thicknessViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func thicknessComboBoxAction(_ sender: Any) {
- thickness_Slider.floatValue = Float(thickness_ComboBox.floatValue)
- let thickness = CGFloat(thickness_Slider.floatValue)
-
- annotationModel.setLineWidth(thickness)
- thicknessViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func lineStyleButtonAction(_ sender: NSButton) {
- if sender.tag == 0 {
- annotationModel.setStyle(.solid)
- } else {
- annotationModel.setStyle(.dashed)
- annotation?.setDashPattern(annotationModel.dashPattern())
- }
- lineStyleViewRefresh()
- updateAnnotation()
- }
-
- @IBAction func startMenuItemAction(_ sender: NSMenuItem) {
- let startType: CPDFLineStyle = (CPDFLineStyle(rawValue: sender.tag) ?? CPDFLineStyle(rawValue: 0))!
- annotationModel.setStart(startType)
- updateAnnotation()
- }
-
- @IBAction func endMenuItemAction(_ sender: NSMenuItem) {
- let endType: CPDFLineStyle = (CPDFLineStyle(rawValue: sender.tag) ?? CPDFLineStyle(rawValue: 0))!
- annotationModel.setEnd(endType)
- updateAnnotation()
- }
-
- @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)
- }
- }
-
- 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.fontName() {
- let font = NSFont(name: data, size: annotationModel.fontSize()) ?? NSFont.systemFont(ofSize: 16)
- let newFont = NSFont(name: font.fontName, size: CGFloat(font_SizeComboBox.floatValue))
- if let newFont = newFont {
- annotationModel.setFontName(newFont.fontName)
- annotationModel.setFontSize(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.fontName() {
- let font = NSFont(name: data, size: annotationModel.fontSize()) ?? 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.setFontName(newFont.fontName)
- annotationModel.setFontSize(newFont.pointSize)
- }
- }
- }
- }
- }
- }
- 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 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
- }
- return .unkown
- }
- }
-
- // MARK: Notification
- @objc func textFieldDidEndEditingNotification(_ notification: Notification) {
- if lineStyle_TextField.stringValue.isEmpty == true {
- return
- }
-
- if isNumericUsingNSRegularExpression(lineStyle_TextField.stringValue) == false {
- lineStyle_TextField.stringValue = "5"
- return
- }
-
- var dashFloat = Float(lineStyle_TextField.stringValue)
- if dashFloat == 0 {
- lineStyle_TextField.stringValue = "1"
- dashFloat = 1.0
- }
- let number = NSNumber(value: dashFloat!)
- var lineDashPattern: [Any] = annotationModel.dashPattern()
- let array: [NSNumber]
- if annotationModel.dashPattern() is [NSNumber] {
- if lineDashPattern.isEmpty {
- array = [number]
- } else {
- lineDashPattern[0] = number
- array = lineDashPattern as! [NSNumber]
- }
- } else {
- array = [number]
- }
-
- annotation?.setDashPattern(array)
- updateAnnotation()
- }
- }
|