// // KMSignatureWindowController.swift // PDF Reader Pro // // Created by lizhe on 2023/10/10. // import Cocoa var recentlyFonts: [String] = [] class KMSignatureColorButton: NSButton { var circleColor: NSColor? var drawImage: NSImage? override init(frame frameRect: NSRect) { super.init(frame: frameRect) wantsLayer = true layer?.cornerRadius = 12 layer?.masksToBounds = true layer?.borderWidth = 1.5 } required init?(coder: NSCoder) { super.init(coder: coder) wantsLayer = true layer?.cornerRadius = 12 layer?.masksToBounds = true layer?.borderWidth = 1.5 } override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) if let circleColor = circleColor { let path = NSBezierPath(ovalIn: NSRect(x: 3, y: 3, width: dirtyRect.size.width - 6, height: dirtyRect.size.height - 6)) circleColor.set() path.fill() } else if let drawImage = drawImage { drawImage.draw(in: NSRect(x: 3, y: 3, width: dirtyRect.size.width - 6, height: dirtyRect.size.height - 6), from: NSZeroRect, operation: .sourceOver, fraction: 1.0) } } } class KMSignatureButton: NSButton { override func menu(for event: NSEvent) -> NSMenu? { let menu = NSMenu(title: "") let deleteItem = menu.addItem(withTitle: NSLocalizedString("Delete", comment: ""), action: #selector(deleteSignature), keyEquivalent: "") deleteItem.target = self let exportItem = menu.addItem(withTitle: NSLocalizedString("Export", comment: ""), action: nil, keyEquivalent: "") let submenu = NSMenu() let pngItem = submenu.insertItem(withTitle: NSLocalizedString("PNG", comment: ""), action: #selector(export(_:)), keyEquivalent: "", at: 0) pngItem.tag = 0 let jpgItem = submenu.insertItem(withTitle: NSLocalizedString("JPG", comment: ""), action: #selector(export(_:)), keyEquivalent: "", at: 1) jpgItem.tag = 1 let pdfItem = submenu.insertItem(withTitle: NSLocalizedString("PDF", comment: ""), action: #selector(export(_:)), keyEquivalent: "", at: 2) pdfItem.tag = 2 exportItem.submenu = submenu return menu } @objc private func deleteSignature() { NotificationCenter.default.post(name: NSNotification.Name("kKMSignatureDeleteNotification"), object: NSNumber(value: self.tag)) } @objc private func export(_ sender: NSMenuItem) { let index = self.tag let type = sender.tag let signatureManager = KMSignatureManager() signatureManager.loadAllSignatureList() let signature = signatureManager.signatureList[index] let image = signature.pathsImage if type == 0 { if let tiffData = image.tiffRepresentation, let imageRep = NSBitmapImageRep(data: tiffData) { imageRep.size = image.size if let imageData = imageRep.representation(using: .png, properties: [:]) { let savePanel = NSSavePanel() savePanel.allowedFileTypes = ["png"] savePanel.beginSheetModal(for: self.window!) { response in if response.rawValue == NSApplication.ModalResponse.OK.rawValue, let url = savePanel.url { do { try imageData.write(to: url, options: .atomic) NSWorkspace.shared.selectFile(url.path, inFileViewerRootedAtPath: "") } catch { // Handle error } } } } } } else if type == 1 { if let tiffData = image.tiffRepresentation, let imageRep = NSBitmapImageRep(data: tiffData) { imageRep.size = image.size if let imageData = imageRep.representation(using: .jpeg, properties: [:]) { let savePanel = NSSavePanel() savePanel.allowedFileTypes = ["jpg"] savePanel.beginSheetModal(for: self.window!) { response in if response.rawValue == NSApplication.ModalResponse.OK.rawValue, let url = savePanel.url { do { try imageData.write(to: url, options: .atomic) NSWorkspace.shared.selectFile(url.path, inFileViewerRootedAtPath: "") } catch { // Handle error } } } } } } else { let pdf = CPDFDocument() let signatureImagePath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("signatureImage.png") if let tiffData = image.tiffRepresentation { try? tiffData.write(to: URL(fileURLWithPath: signatureImagePath), options: .atomic) } pdf!.insertPage(image.size, withImage: signatureImagePath, at: 0) let savePanel = NSSavePanel() savePanel.allowedFileTypes = ["pdf"] savePanel.beginSheetModal(for: NSApp.mainWindow!) { response in if response.rawValue == NSApplication.ModalResponse.OK.rawValue, let url = savePanel.url { do { try pdf!.write(to: url) NSWorkspace.shared.selectFile(url.path, inFileViewerRootedAtPath: "") } catch { // Handle error } } } } } } var windowController_signature: KMSignatureWindowController? @objcMembers class KMSignatureWindowController: NSWindowController, KMDrawViewDelegate, KMSelectPopButtonDelegate, KMChangeSignatureTextDelegate { @IBOutlet weak var cancelBtton: NSButton! @IBOutlet weak var applyButton: NSButton! var cancelButtonVC: KMDesignButton! var applyButtonVC: KMDesignButton! @IBOutlet weak var clearButton: NSButton! @IBOutlet var signTypeView: NSView! @IBOutlet weak var inputButton: NSButton! @IBOutlet weak var drawingButton: NSButton! @IBOutlet weak var pictureButton: NSButton! @IBOutlet var signTypeBackView: NSView! @IBOutlet weak var trackpadLabel: NSTextField! @IBOutlet weak var contentBox: NSBox! @IBOutlet weak var titleLabel: NSTextField! // Keyboard @IBOutlet var inputView: NSView! @IBOutlet weak var keyboardView: KMPDFSignatureTextView! @IBOutlet weak var fontBox: NSPopUpButton! @IBOutlet var keyboardColorBtn1: NSButton! @IBOutlet var keyboardColorBtn2: NSButton! @IBOutlet var keyboardColorBtn3: NSButton! @IBOutlet var keyboardColorBtn4: NSButton! @IBOutlet var keyboardColorSelView: NSView! @IBOutlet weak var textColorButton: KMSignatureColorButton! var fontVC: KMDesignSelect! var fontValues: [String] = [] var fontDefaultValue: String = "Helvetica" // Draw @IBOutlet var drawingView: NSView! @IBOutlet weak var drawView: KMDrawView! @IBOutlet weak var trackpadButton: NSButton! var trackpadButtonVC: KMDesignButton! @IBOutlet var drawSizeBox: NSPopUpButton! @IBOutlet var colorBGView: NSView! @IBOutlet var drawColorSelView: NSView! @IBOutlet var drawColorBtn1: NSButton! @IBOutlet var drawColorBtn2: NSButton! @IBOutlet var drawColorBtn3: NSButton! @IBOutlet var drawColorBtn4: NSButton! var drawSizeVC: KMDesignSelect! var drawSizeValues = ["1.0","2.0","4.0","6.0","8.0"] var drawSizeDefaultValue: String = "2.0" @IBOutlet var drawTipView: NSView! @IBOutlet var drawTipLabel: NSTextField! // Picture @IBOutlet var pictureView: NSView! @IBOutlet weak var pictureBackView: KMPDFSignatureImageView! @IBOutlet var pictureClearBackBtn: NSButton! var pictureClearBackBtnVC: KMDesignButton! @IBOutlet weak var pictureHelpButton: KMCoverButton! var selectedSignature: KMSignature! var selectItem: NSMenuItem! var type: KMPDFSignatureType! { didSet { self.setType(type) } } var handler: ((KMSignature) -> Void)! var popover: NSPopover! override func windowDidLoad() { super.windowDidLoad() weak var weakSelf = self self.type = .text self.cancelBtton.title = "" self.cancelButtonVC = KMDesignButton(withType: .Text) self.cancelBtton.addSubview(self.cancelButtonVC.view) self.cancelButtonVC.view.frame = self.cancelBtton.bounds self.cancelButtonVC.view.autoresizingMask = [.width, .height] self.cancelButtonVC.stringValue = NSLocalizedString("Cancel", comment: "") self.cancelButtonVC.target = self self.cancelButtonVC.action = #selector(dismissSheet(_:)) self.cancelButtonVC.button(type: .Sec_Icon, size: .m) self.clearButton.target = self self.clearButton.action = #selector(clearButton_Click(_:)) self.clearButton.isHidden = true self.applyButton.title = "" self.applyButtonVC = KMDesignButton(withType: .Text) self.applyButton.addSubview(self.applyButtonVC.view) self.applyButtonVC.view.frame = self.applyButton.bounds self.applyButtonVC.view.autoresizingMask = [.width, .height] self.applyButtonVC.stringValue = NSLocalizedString("Save", comment: "") self.applyButtonVC.target = self self.applyButtonVC.action = #selector(applyButton_Click(_:)) self.applyButtonVC.button(type: .Cta, size: .m) self.applyButtonVC.enabled = false self.contentBox.wantsLayer = true self.contentBox.layer?.backgroundColor = NSColor.clear.cgColor self.contentBox.borderType = .noBorder self.inputButton.isBordered = false self.drawingButton.isBordered = false self.pictureButton.isBordered = false // Keyboard self.inputView.wantsLayer = true self.inputView.layer?.backgroundColor = NSColor.white.cgColor self.keyboardView.wantsLayer = true self.keyboardView.layer?.backgroundColor = NSColor(red: 247/255.0, green: 248/255.0, blue: 250/255.0, alpha: 1.0).cgColor self.keyboardView.changeSignatureTextCallback = { isTrue in if isTrue { weakSelf?.clearButton.isHidden = false weakSelf?.clearButton.title = NSLocalizedString("Clear", comment: "") } else { weakSelf?.clearButton.isHidden = true } } keyboardColorBtn1.wantsLayer = true keyboardColorBtn2.wantsLayer = true keyboardColorBtn3.wantsLayer = true keyboardColorBtn4.wantsLayer = true keyboardColorBtn1.layer?.backgroundColor = NSColor(red: 0, green: 0, blue: 0, alpha: 1.0).cgColor keyboardColorBtn2.layer?.backgroundColor = NSColor(red: 252/255.0, green: 31/255.0, blue: 31/255.0, alpha: 1.0).cgColor keyboardColorBtn3.layer?.backgroundColor = NSColor(red: 39/255.0, green: 60/255.0, blue: 98/255.0, alpha: 1.0).cgColor keyboardColorBtn4.layer?.backgroundColor = NSColor(red: 148/255.0, green: 152/255.0, blue: 156/255.0, alpha: 1.0).cgColor let cornerRadius: CGFloat = 10.0 keyboardColorBtn1.layer?.cornerRadius = cornerRadius keyboardColorBtn2.layer?.cornerRadius = cornerRadius keyboardColorBtn3.layer?.cornerRadius = cornerRadius keyboardColorBtn4.layer?.cornerRadius = cornerRadius keyboardColorBtn1.layer?.masksToBounds = true keyboardColorBtn2.layer?.masksToBounds = true keyboardColorBtn3.layer?.masksToBounds = true keyboardColorBtn4.layer?.masksToBounds = true keyboardColorSelView.wantsLayer = true keyboardColorSelView.layer?.backgroundColor = NSColor(red: 206/255.0, green: 208/255.0, blue: 212/255.0, alpha: 0.6).cgColor keyboardColorSelView.layer?.borderWidth = 1.0 keyboardColorSelView.layer?.borderColor = NSColor(red: 206/255.0, green: 208/255.0, blue: 212/255.0, alpha: 1.0).cgColor keyboardColorSelView.layer?.cornerRadius = 4.0 keyboardColorSelView.layer?.masksToBounds = true self.colorTextButtonAction(self.keyboardColorBtn1) // Draw self.drawView.delegate = self self.drawView.wantsLayer = true self.drawView.strokeRadius = CGFloat(((self.drawSizeDefaultValue as? NSString) ?? "0") .floatValue) self.drawView.layer?.cornerRadius = 4.0 self.drawView.layer?.masksToBounds = true self.drawView.layer?.borderWidth = 1.0 self.drawView.layer?.borderColor = NSColor(red: 223/255.0, green: 225/255.0, blue: 229/255.0, alpha: 1.0).cgColor self.drawView.layer?.backgroundColor = NSColor(red: 247/255.0, green: 248/255.0, blue: 250/255.0, alpha: 1.0).cgColor drawColorBtn1.wantsLayer = true drawColorBtn2.wantsLayer = true drawColorBtn3.wantsLayer = true drawColorBtn4.wantsLayer = true drawColorBtn1.layer?.backgroundColor = NSColor(red: 37/255.0, green: 38/255.0, blue: 41/255.0, alpha: 1.0).cgColor drawColorBtn2.layer?.backgroundColor = NSColor(red: 252/255.0, green: 31/255.0, blue: 31/255.0, alpha: 1.0).cgColor drawColorBtn3.layer?.backgroundColor = NSColor(red: 39/255.0, green: 60/255.0, blue: 98/255.0, alpha: 1.0).cgColor drawColorBtn4.layer?.backgroundColor = NSColor(red: 148/255.0, green: 152/255.0, blue: 156/255.0, alpha: 1.0).cgColor drawColorBtn1.layer?.cornerRadius = cornerRadius drawColorBtn2.layer?.cornerRadius = cornerRadius drawColorBtn3.layer?.cornerRadius = cornerRadius drawColorBtn4.layer?.cornerRadius = cornerRadius drawColorBtn1.layer?.masksToBounds = true drawColorBtn2.layer?.masksToBounds = true drawColorBtn3.layer?.masksToBounds = true drawColorBtn4.layer?.masksToBounds = true drawColorSelView.wantsLayer = true drawColorSelView.layer?.backgroundColor = NSColor(red: 206/255.0, green: 208/255.0, blue: 212/255.0, alpha: 0.6).cgColor drawColorSelView.layer?.borderWidth = 1.0 drawColorSelView.layer?.borderColor = NSColor(red: 206/255.0, green: 208/255.0, blue: 212/255.0, alpha: 1.0).cgColor drawColorSelView.layer?.cornerRadius = 4.0 drawColorSelView.layer?.masksToBounds = true self.drawColorBtnClicked(self.drawColorBtn1) for pxSize in ["0.5", "1.0", "1.5", "2.0", "2.5", "3.0"] { let attrited: [NSAttributedString.Key: Any] = [.font: NSFont.systemFont(ofSize: 14)] let string = NSAttributedString(string: pxSize, attributes: attrited) let item = NSMenuItem() item.attributedTitle = string self.drawSizeBox.menu?.addItem(item) } self.drawSizeBox.selectItem(at: 1) self.drawSizeBox.title = "1.0 pt" // Picture self.pictureView.wantsLayer = true self.pictureView.layer?.backgroundColor = NSColor.white.cgColor self.pictureBackView.wantsLayer = true self.pictureBackView.layer?.cornerRadius = 4.0 self.pictureBackView.layer?.masksToBounds = true self.pictureBackView.layer?.borderWidth = 1.0 self.pictureBackView.layer?.borderColor = NSColor(red: 223/255.0, green: 225/255.0, blue: 229/255.0, alpha: 1.0).cgColor self.pictureBackView.layer?.backgroundColor = NSColor(red: 247/255.0, green: 248/255.0, blue: 250/255.0, alpha: 1.0).cgColor self.pictureBackView.changeSignatureImageCallback = { isTrue in if isTrue { weakSelf?.applyButtonVC.enabled = true } else { weakSelf?.applyButtonVC.enabled = false } if let image = weakSelf?.pictureBackView.signatureImage { weakSelf?.clearButton.isHidden = false weakSelf?.clearButton.title = NSLocalizedString("Reselect", comment: "") } else { weakSelf?.clearButton.isHidden = true } } self.trackpadLabel.isHidden = true self.drawTipView.isHidden = true self.keyboardView.delegate = self self.drawView.changeDrawCallback = { isTrue in if isTrue { weakSelf?.applyButtonVC.enabled = true } else { weakSelf?.applyButtonVC.enabled = false } } self.drawView.touchEndCallback = { isClear in if isClear { weakSelf?.clearButton.isHidden = true } else { weakSelf?.clearButton.isHidden = false weakSelf?.clearButton.title = NSLocalizedString("Clear", comment: "") } } self.inputButton_Click(self.inputButton) self.pictureHelpButton.image = NSImage(named: "KMImageNameHelpNormal") self.pictureHelpButton.toolTip = "Remove white background from images" self.pictureHelpButton.action = #selector(showHelpTip(_:)) self.pictureHelpButton.coverAction = { button, action in if action == .enter { button.image = NSImage(named: "KMImageNameHelpHover") // [weakSelf showHelpTip:button] } else if action == .exit { button.image = NSImage(named: "KMImageNameHelpNormal") // [weakSelf dismissHelpTip] } } localizedString() setupUI() } func setupUI() { let fontName = "SFProText-Regular" titleLabel.font = NSFont(name: "SFProText-Semibold", size: 16) titleLabel.textColor = NSColor(red: 37/255.0, green: 38/255.0, blue: 41/255.0, alpha: 1.0) signTypeView.wantsLayer = true signTypeView.layer?.backgroundColor = NSColor(red: 223/255.0, green: 225/255.0, blue: 229/255.0, alpha: 1.0).cgColor signTypeView.layer?.cornerRadius = 4.0 signTypeView.layer?.masksToBounds = true signTypeBackView.wantsLayer = true signTypeBackView.layer?.cornerRadius = 2.0 signTypeBackView.layer?.masksToBounds = true signTypeBackView.layer?.backgroundColor = NSColor.white.cgColor for button in [inputButton, drawingButton, pictureButton] { button?.setTitleColor(NSColor(red: 37/255.0, green: 38/255.0, blue: 41/255.0, alpha: 1.0)) button?.font = NSFont(name: fontName, size: 12) } let fonts = CPDFAnnotationModel.supportFonts().compactMap { ($0 as AnyObject).allKeys.first } self.fontValues = fonts // Input fontVC = KMDesignSelect(withType: .Combox) fontBox.superview?.addSubview(fontVC.view) fontVC.view.translatesAutoresizingMaskIntoConstraints = false fontVC.view.leftAnchor.constraint(equalTo: fontBox.leftAnchor).isActive = true fontVC.view.centerYAnchor.constraint(equalTo: fontBox.centerYAnchor).isActive = true fontVC.view.widthAnchor.constraint(equalToConstant: 200).isActive = true fontBox.isHidden = true fontVC.delete = self fontVC.addItems(withObjectValues: fontValues) fontVC.stringValue = fontDefaultValue // Drawing drawSizeVC = KMDesignSelect(withType: .Combox) drawingView.addSubview(drawSizeVC.view) drawSizeVC.view.translatesAutoresizingMaskIntoConstraints = false drawSizeVC.view.leftAnchor.constraint(equalTo: drawSizeBox.leftAnchor).isActive = true drawSizeVC.view.centerYAnchor.constraint(equalTo: drawSizeBox.centerYAnchor).isActive = true drawSizeVC.view.widthAnchor.constraint(equalToConstant: 85).isActive = true drawSizeBox.isHidden = true drawSizeVC.delete = self var drawSizes = [String]() for value in drawSizeValues { drawSizes.append("\(value) pt") } drawSizeVC.addItems(withObjectValues: drawSizes) drawSizeVC.stringValue = "\(String(describing: drawSizeDefaultValue)) pt" trackpadButton.title = NSLocalizedString("Trackpad", comment: "") trackpadButton.setTitleColor(NSColor.clear) trackpadButtonVC = KMDesignButton(withType: .CheckBox) trackpadButton.addSubview(trackpadButtonVC.view) trackpadButtonVC.stringValue = NSLocalizedString("Trackpad", comment: "") trackpadButtonVC.state = .Norm trackpadButtonVC.checkbox_radio(imageHeight: NSLayoutConstraint()) trackpadButtonVC.target = self trackpadButtonVC.action = #selector(trackpadButton_Click) var rect = trackpadButtonVC.view.frame rect.origin.y = rect.origin.y - 8 trackpadButtonVC.view.frame = rect // trackpadButtonVC.view.translatesAutoresizingMaskIntoConstraints = false // trackpadButtonVC.view.leftAnchor.constraint(equalTo: trackpadButton.leftAnchor).isActive = true // trackpadButtonVC.view.centerYAnchor.constraint(equalTo: drawSizeVC.view.centerYAnchor).isActive = true // trackpadButtonVC.view.widthAnchor.constraint(equalToConstant: 120).isActive = true // trackpadButton.isHidden = true drawTipView.wantsLayer = true drawTipView.layer?.backgroundColor = NSColor(red: 189/255.0, green: 223/255.0, blue: 253/255.0, alpha: 1.0).cgColor drawTipLabel.stringValue = NSLocalizedString("Press any key to disable the touchpad", comment: "") drawTipLabel.textColor = NSColor(red: 37/255.0, green: 38/255.0, blue: 41/255.0, alpha: 1.0) drawTipLabel.font = NSFont(name: "SFProText-Regular", size: 14) // Picture pictureBackView.emptyTipLbl.textColor = NSColor(red: 148/255.0, green: 152/255.0, blue: 156/255.0, alpha: 1.0) pictureBackView.emptyTipLbl.font = NSFont(name: fontName, size: 14) pictureClearBackBtn.title = NSLocalizedString("Clear background", comment: "") pictureClearBackBtn.setTitleColor(.clear) pictureClearBackBtnVC = KMDesignButton(withType: .CheckBox) pictureClearBackBtn.addSubview(pictureClearBackBtnVC.view) pictureClearBackBtnVC.stringValue = NSLocalizedString("Clear background", comment: "") pictureClearBackBtnVC.state = .Norm pictureClearBackBtnVC.checkbox_radio(imageHeight: NSLayoutConstraint()) pictureClearBackBtnVC.target = self pictureClearBackBtnVC.action = #selector(pictureClearBackBtnAction(_:)) pictureClearBackBtnVC.view.translatesAutoresizingMaskIntoConstraints = false pictureClearBackBtnVC.view.mas_makeConstraints { make in make?.edges.equalTo() } } func setType(_ type: KMPDFSignatureType) { // self.type = type var rect = self.signTypeBackView.frame if type == .text { rect.origin.x = 1 } else if type == .ink { rect.origin.x = 2 + 75 } else if type == .image { rect.origin.x = 2 + 75 * 2 } rect.origin.y = (self.signTypeBackView.superview!.frame.height - self.signTypeBackView.frame.height) / 2.0 self.signTypeBackView.frame = rect self.clearButton.isHidden = true if type == .text { } else if type == .ink { } else if type == .image { if self.pictureBackView.signatureImage != nil { self.clearButton.title = NSLocalizedString("Reselect", comment: "") self.clearButton.isHidden = false } } } override func mouseDown(with event: NSEvent) { dismissHelpTip() } func localizedString() { self.titleLabel.stringValue = NSLocalizedString("Create Signature", comment: "") self.trackpadButton.title = (NSLocalizedString("Trackpad", comment: "")) self.clearButton.title = (NSLocalizedString("Clear", comment: "")) self.trackpadLabel.stringValue = NSLocalizedString("Press \"esc\" to disable the Trackpad.", comment: "") let selectorFonts = ["Mistral", "Bradley Hand", "Brush Script MT", "SignPainter", "Edwardian Script ITC", "American Typewriter", "Baoli SC", "Snell Roundhand", "Apple Chancery", "Monotype Corsiva"] let fonts = NSFontManager.shared.availableFontFamilies for fontName in fonts { let attributes: [NSAttributedString.Key: Any] = [.font: NSFont(name: fontName, size: 12.0)!] let attributedString = NSAttributedString(string: fontName, attributes: attributes) let item = NSMenuItem() item.attributedTitle = attributedString self.fontBox.menu?.addItem(item) } var fontName: String? = nil if recentlyFonts.count < 1 { for name in selectorFonts { if fonts.contains(name) { fontName = name break } } if let fontName = fontName { recentlyFonts.append(fontName) } } else { fontName = recentlyFonts.first } self.keyboardView.fontName = self.fontDefaultValue ?? "" for (index, fontName) in recentlyFonts.enumerated() { let attributes: [NSAttributedString.Key: Any] = [.font: NSFont(name: fontName, size: 12.0)!] let attributedString = NSAttributedString(string: fontName, attributes: attributes) let item = NSMenuItem() item.attributedTitle = attributedString self.fontBox.menu?.insertItem(item, at: 1 + index) } let sep = NSMenuItem.separator() self.fontBox.menu?.insertItem(sep, at: recentlyFonts.count + 1) self.selectItem = self.fontBox.menu?.item(at: 1) self.selectItem?.state = .on self.inputButton.title = NSLocalizedString("Keyboard", comment: "") self.drawingButton.title = NSLocalizedString("Trackpad", comment: "") self.pictureButton.title = NSLocalizedString("Image", comment: "") } @objc func showHelpTip(_ sender: NSButton) { if self.popover != nil { dismissHelpTip() return } let pop = NSPopover() self.popover = pop let controller = KMSignatureHelpViewController() pop.contentViewController = controller controller.tipString = NSLocalizedString("Remove white background from images", comment: "") pop.setValue(true, forKey: "shouldHideAnchor") pop.show(relativeTo: NSMakeRect(0, -8, sender.bounds.width, sender.bounds.height), of: sender, preferredEdge: .maxY) } func dismissHelpTip() { self.popover?.close() self.popover = nil } @IBAction func inputButton_Click(_ sender: Any) { self.contentBox.contentView = self.inputView self.type = .text } @IBAction func drawingButton_Click(_ sender: Any) { self.contentBox.contentView = self.drawingView self.type = .ink } @IBAction func pictureButton_Click(_ sender: Any) { self.contentBox.contentView = self.pictureView self.type = .image } @objc func clearButton_Click(_ sender: Any) { if self.type == .image { self.pictureBackView.reSelectImage() } else if self.type == .ink { self.drawView.clearImage() } else if self.type == .text { self.keyboardView.clearImage() } self.applyButtonVC.enabled = false } @objc func applyButton_Click(_ sender: Any) { let signature = KMSignature() if self.type == .text { if let image = self.keyboardView.signatureImage() { signature.pathsImage = image signature.signatureType = .text let signatureManager = KMSignatureManager() signatureManager.loadAllSignatureList() signatureManager.addSignature(signature) signatureManager.saveSingaturesToFile() } else { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Unable to add new signatures. Please try again.", comment: "") alert.runModal() return } } else if self.type == .image { if let image = self.pictureBackView.signatureImage() { signature.pathsImage = image signature.signatureType = .image let signatureManager = KMSignatureManager() signatureManager.loadAllSignatureList() signatureManager.addSignature(signature) signatureManager.saveSingaturesToFile() } else { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Unable to add new signatures. Please try again.", comment: "") alert.runModal() return } } else { if let image = self.drawView.signatureImage() { signature.addPath(self.drawView.drawBezierPath) signature.signatureType = .ink signature.signatureColor = self.drawView.drawColor signature.pathsImage = image let signatureManager = KMSignatureManager() signatureManager.loadAllSignatureList() signatureManager.addSignature(signature) signatureManager.saveSingaturesToFile() } else { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Unable to add new signatures. Please try again.", comment: "") alert.runModal() return } } self.selectedSignature = signature dismissSheet(nil) } @IBAction func trackpadButton_Click(_ sender: Any) { if self.trackpadButtonVC.state == .Checked { self.trackpadButtonVC.state = .Norm self.trackpadLabel.isHidden = true self.drawTipView.isHidden = true self.drawView.isAcceptsTouch = false } else { self.trackpadButtonVC.state = .Checked self.trackpadLabel.isHidden = true self.drawTipView.isHidden = false self.drawView.isAcceptsTouch = true DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { self.drawTipView.isHidden = true } } } @IBAction func boxItemClicked_Font(_ sender: Any) { if let name = self.fontBox.selectedItem?.title { self.fontBox.title = name self.keyboardView.fontName = name if recentlyFonts.contains(name) { if let index = recentlyFonts.firstIndex(of: name) { recentlyFonts.remove(at: index) self.fontBox.menu?.removeItem(at: index + 1) } } if recentlyFonts.count > 0 { recentlyFonts.insert(name, at: 0) } else { recentlyFonts.append(name) } if recentlyFonts.count > 5 { recentlyFonts.removeLast() self.fontBox.menu?.removeItem(at: recentlyFonts.count) } let attributes: [NSAttributedString.Key: Any] = [.font: NSFont(name: name, size: 12.0)!] let attributedString = NSAttributedString(string: name, attributes: attributes) let item = NSMenuItem() item.attributedTitle = attributedString self.fontBox.menu?.insertItem(item, at: 1) self.selectItem?.state = .off self.selectItem = self.fontBox.menu?.item(at: 1) self.selectItem?.state = .on } } @IBAction func colorTextButtonAction(_ sender: Any) { if let button = sender as? NSButton { if button == self.keyboardColorBtn1 || button == self.keyboardColorBtn2 || button == self.keyboardColorBtn3 || button == self.keyboardColorBtn4 { if let color = NSColor(cgColor: button.layer!.backgroundColor!) { self.keyboardView.keyboardColor = color var rect = self.keyboardView.frame rect.origin.y = button.frame.midY - 16 rect.origin.x = button.frame.midX - 16 rect.size.width = 32 rect.size.height = 32 self.keyboardColorSelView.frame = rect } } else { NSColorPanel.shared.setTarget(self) NSColorPanel.shared.setAction(#selector(keyboardColorPanelColorDidChange(_:))) NSColorPanel.shared.orderFront(nil) } } } @IBAction func drawColorBtnClicked(_ sender: NSButton) { if sender == self.drawColorBtn1 || sender == self.drawColorBtn2 || sender == self.drawColorBtn3 || sender == self.drawColorBtn4 { if let color = NSColor(cgColor: sender.layer!.backgroundColor!) { self.drawView.drawColor = color var rect = self.drawColorSelView.frame rect.origin.y = sender.frame.midY - 16 rect.origin.x = sender.frame.midX - 16 rect.size.width = 32 rect.size.height = 32 self.drawColorSelView.frame = rect } } } @IBAction func drawSizeBtnClicked(_ sender: NSPopUpButton) { let name = self.drawSizeBox.selectedItem?.title self.drawSizeBox.title = name ?? "" let array = [0.5, 1.0, 1.5, 2.0, 2.5, 3.0] let index = self.drawSizeBox.indexOfSelectedItem - 1 self.drawView.strokeRadius = array[index] } @objc @IBAction func pictureClearBackBtnAction(_ sender: NSButton) { var clearBack = true if self.pictureClearBackBtnVC.state == .Checked { self.pictureClearBackBtnVC.state = .Norm clearBack = false } else { self.pictureClearBackBtnVC.state = .Checked clearBack = true } self.pictureBackView.clearBackground = clearBack } @objc func keyboardColorPanelColorDidChange(_ sender: Any) { self.textColorButton.layer?.borderColor = NSColor.clear.cgColor let color = NSColorPanel.shared.color let red = CGFloat(color.redComponent) let green = CGFloat(color.greenComponent) let blue = CGFloat(color.blueComponent) let alpha = CGFloat(color.alphaComponent) self.keyboardView.keyboardColor = color self.textColorButton.layer?.borderColor = NSColor(red: 33.0/255.0, green: 124.0/255.0, blue: 234.0/255.0, alpha: 1.0).cgColor } func drawViewDidFinishTouchMode(_ view: KMDrawView) { self.trackpadButtonVC.state = .Norm self.trackpadLabel.isHidden = true self.drawTipView.isHidden = true } func changeSignatureText(_ isTrue: Bool) { self.applyButtonVC.enabled = isTrue } @objc func didEndSheet(_ sheet: NSWindow?, returnCode: Int, contextInfo: UnsafeMutableRawPointer?) { if contextInfo != nil && self.handler != nil { self.handler!(self.selectedSignature) } } func beginSheetModal(for window: NSWindow?, completionHandler handler: ((KMSignature) -> Void)?) { windowController_signature = self if window != nil { window!.beginSheet(self.window!) { ModalResponse in if self.selectedSignature != nil { self.handler?(self.selectedSignature) } } } self.handler = handler } @objc func dismissSheet(_ sender: Any?) { windowController_signature = nil if sender != nil { NSApp.endSheet(self.window!, returnCode: 0) } else { NSApp.endSheet(self.window!, returnCode: 1) } self.window?.orderOut(self) } func km_comboBoxSelectionDidChange(_ obj: KMDesignSelect) { if obj == fontVC { var index = fontVC.indexOfSelectedItem if index < 0 { index = 0 } keyboardView.fontName = fontVC.items[index] } else if obj == drawSizeVC { var index = drawSizeVC.indexOfSelectedItem if index < 0 { index = 0 } drawView.strokeRadius = CGFloat((drawSizeValues[index] as! NSString).floatValue) } } func tabView(_ tabView: NSTabView, shouldSelect tabViewItem: NSTabViewItem?) -> Bool { return true } func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) { var isImage = false if tabView.indexOfTabViewItem(tabViewItem!) == 0 { self.type = .text if self.keyboardView.signatureImage() != nil { isImage = true } } else if tabView.indexOfTabViewItem(tabViewItem!) == 1 { self.type = .ink if self.drawView.signatureImage() != nil { isImage = true } } else if tabView.indexOfTabViewItem(tabViewItem!) == 2 { self.type = .image if self.pictureBackView.signatureImage() != nil { isImage = true } } if isImage { self.applyButtonVC.enabled = true } else { self.applyButtonVC.enabled = false } } }