KMSignatureWindowController.swift 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909
  1. //
  2. // KMSignatureWindowController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by lizhe on 2023/10/10.
  6. //
  7. import Cocoa
  8. var recentlyFonts: [String] = []
  9. class KMSignatureColorButton: NSButton {
  10. var circleColor: NSColor?
  11. var drawImage: NSImage?
  12. override init(frame frameRect: NSRect) {
  13. super.init(frame: frameRect)
  14. wantsLayer = true
  15. layer?.cornerRadius = 12
  16. layer?.masksToBounds = true
  17. layer?.borderWidth = 1.5
  18. }
  19. required init?(coder: NSCoder) {
  20. super.init(coder: coder)
  21. wantsLayer = true
  22. layer?.cornerRadius = 12
  23. layer?.masksToBounds = true
  24. layer?.borderWidth = 1.5
  25. }
  26. override func draw(_ dirtyRect: NSRect) {
  27. super.draw(dirtyRect)
  28. if let circleColor = circleColor {
  29. let path = NSBezierPath(ovalIn: NSRect(x: 3, y: 3, width: dirtyRect.size.width - 6, height: dirtyRect.size.height - 6))
  30. circleColor.set()
  31. path.fill()
  32. } else if let drawImage = drawImage {
  33. 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)
  34. }
  35. }
  36. }
  37. class KMSignatureButton: NSButton {
  38. override func menu(for event: NSEvent) -> NSMenu? {
  39. let menu = NSMenu(title: "")
  40. let deleteItem = menu.addItem(withTitle: NSLocalizedString("Delete", comment: ""), action: #selector(deleteSignature), keyEquivalent: "")
  41. deleteItem.target = self
  42. let exportItem = menu.addItem(withTitle: NSLocalizedString("Export", comment: ""), action: nil, keyEquivalent: "")
  43. let submenu = NSMenu()
  44. let pngItem = submenu.insertItem(withTitle: NSLocalizedString("PNG", comment: ""), action: #selector(export(_:)), keyEquivalent: "", at: 0)
  45. pngItem.tag = 0
  46. let jpgItem = submenu.insertItem(withTitle: NSLocalizedString("JPG", comment: ""), action: #selector(export(_:)), keyEquivalent: "", at: 1)
  47. jpgItem.tag = 1
  48. let pdfItem = submenu.insertItem(withTitle: NSLocalizedString("PDF", comment: ""), action: #selector(export(_:)), keyEquivalent: "", at: 2)
  49. pdfItem.tag = 2
  50. exportItem.submenu = submenu
  51. return menu
  52. }
  53. @objc private func deleteSignature() {
  54. NotificationCenter.default.post(name: NSNotification.Name("kKMSignatureDeleteNotification"), object: NSNumber(value: self.tag))
  55. }
  56. @objc private func export(_ sender: NSMenuItem) {
  57. let index = self.tag
  58. let type = sender.tag
  59. let signatureManager = KMSignatureManager()
  60. signatureManager.loadAllSignatureList()
  61. let signature = signatureManager.signatureList[index]
  62. let image = signature.pathsImage
  63. if type == 0 {
  64. if let tiffData = image.tiffRepresentation,
  65. let imageRep = NSBitmapImageRep(data: tiffData) {
  66. imageRep.size = image.size
  67. if let imageData = imageRep.representation(using: .png, properties: [:]) {
  68. let savePanel = NSSavePanel()
  69. savePanel.allowedFileTypes = ["png"]
  70. savePanel.beginSheetModal(for: self.window!) { response in
  71. if response.rawValue == NSApplication.ModalResponse.OK.rawValue,
  72. let url = savePanel.url {
  73. do {
  74. try imageData.write(to: url, options: .atomic)
  75. NSWorkspace.shared.selectFile(url.path, inFileViewerRootedAtPath: "")
  76. } catch {
  77. // Handle error
  78. }
  79. }
  80. }
  81. }
  82. }
  83. } else if type == 1 {
  84. if let tiffData = image.tiffRepresentation,
  85. let imageRep = NSBitmapImageRep(data: tiffData) {
  86. imageRep.size = image.size
  87. if let imageData = imageRep.representation(using: .jpeg, properties: [:]) {
  88. let savePanel = NSSavePanel()
  89. savePanel.allowedFileTypes = ["jpg"]
  90. savePanel.beginSheetModal(for: self.window!) { response in
  91. if response.rawValue == NSApplication.ModalResponse.OK.rawValue,
  92. let url = savePanel.url {
  93. do {
  94. try imageData.write(to: url, options: .atomic)
  95. NSWorkspace.shared.selectFile(url.path, inFileViewerRootedAtPath: "")
  96. } catch {
  97. // Handle error
  98. }
  99. }
  100. }
  101. }
  102. }
  103. } else {
  104. let pdf = CPDFDocument()
  105. let signatureImagePath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("signatureImage.png")
  106. if let tiffData = image.tiffRepresentation {
  107. try? tiffData.write(to: URL(fileURLWithPath: signatureImagePath), options: .atomic)
  108. }
  109. pdf!.insertPage(image.size, withImage: signatureImagePath, at: 0)
  110. let savePanel = NSSavePanel()
  111. savePanel.allowedFileTypes = ["pdf"]
  112. savePanel.beginSheetModal(for: NSApp.mainWindow!) { response in
  113. if response.rawValue == NSApplication.ModalResponse.OK.rawValue,
  114. let url = savePanel.url {
  115. do {
  116. try pdf!.write(to: url)
  117. NSWorkspace.shared.selectFile(url.path, inFileViewerRootedAtPath: "")
  118. } catch {
  119. // Handle error
  120. }
  121. }
  122. }
  123. }
  124. }
  125. }
  126. var windowController_signature: KMSignatureWindowController?
  127. @objcMembers class KMSignatureWindowController: NSWindowController, KMDrawViewDelegate, KMSelectPopButtonDelegate, KMChangeSignatureTextDelegate {
  128. @IBOutlet weak var cancelBtton: NSButton!
  129. @IBOutlet weak var applyButton: NSButton!
  130. var cancelButtonVC: KMDesignButton!
  131. var applyButtonVC: KMDesignButton!
  132. @IBOutlet weak var clearButton: NSButton!
  133. @IBOutlet var signTypeView: NSView!
  134. @IBOutlet weak var inputButton: NSButton!
  135. @IBOutlet weak var drawingButton: NSButton!
  136. @IBOutlet weak var pictureButton: NSButton!
  137. @IBOutlet var signTypeBackView: NSView!
  138. @IBOutlet weak var trackpadLabel: NSTextField!
  139. @IBOutlet weak var contentBox: NSBox!
  140. @IBOutlet weak var titleLabel: NSTextField!
  141. // Keyboard
  142. @IBOutlet var inputView: NSView!
  143. @IBOutlet weak var keyboardView: KMPDFSignatureTextView!
  144. @IBOutlet weak var fontBox: NSPopUpButton!
  145. @IBOutlet var keyboardColorBtn1: NSButton!
  146. @IBOutlet var keyboardColorBtn2: NSButton!
  147. @IBOutlet var keyboardColorBtn3: NSButton!
  148. @IBOutlet var keyboardColorBtn4: NSButton!
  149. @IBOutlet var keyboardColorSelView: NSView!
  150. @IBOutlet weak var textColorButton: KMSignatureColorButton!
  151. var fontVC: KMDesignSelect!
  152. var fontValues: [String] = []
  153. var fontDefaultValue: String = "Helvetica"
  154. // Draw
  155. @IBOutlet var drawingView: NSView!
  156. @IBOutlet weak var drawView: KMDrawView!
  157. @IBOutlet weak var trackpadButton: NSButton!
  158. var trackpadButtonVC: KMDesignButton!
  159. @IBOutlet var drawSizeBox: NSPopUpButton!
  160. @IBOutlet var colorBGView: NSView!
  161. @IBOutlet var drawColorSelView: NSView!
  162. @IBOutlet var drawColorBtn1: NSButton!
  163. @IBOutlet var drawColorBtn2: NSButton!
  164. @IBOutlet var drawColorBtn3: NSButton!
  165. @IBOutlet var drawColorBtn4: NSButton!
  166. var drawSizeVC: KMDesignSelect!
  167. var drawSizeValues = ["1.0","2.0","4.0","6.0","8.0"]
  168. var drawSizeDefaultValue: String = "2.0"
  169. @IBOutlet var drawTipView: NSView!
  170. @IBOutlet var drawTipLabel: NSTextField!
  171. // Picture
  172. @IBOutlet var pictureView: NSView!
  173. @IBOutlet weak var pictureBackView: KMPDFSignatureImageView!
  174. @IBOutlet var pictureClearBackBtn: NSButton!
  175. var pictureClearBackBtnVC: KMDesignButton!
  176. @IBOutlet weak var pictureHelpButton: KMCoverButton!
  177. var selectedSignature: KMSignature!
  178. var selectItem: NSMenuItem!
  179. var type: KMPDFSignatureType! {
  180. didSet {
  181. self.setType(type)
  182. }
  183. }
  184. var handler: ((KMSignature) -> Void)!
  185. var popover: NSPopover!
  186. override func windowDidLoad() {
  187. super.windowDidLoad()
  188. weak var weakSelf = self
  189. self.type = .text
  190. self.cancelBtton.title = ""
  191. self.cancelButtonVC = KMDesignButton(withType: .Text)
  192. self.cancelBtton.addSubview(self.cancelButtonVC.view)
  193. self.cancelButtonVC.view.frame = self.cancelBtton.bounds
  194. self.cancelButtonVC.view.autoresizingMask = [.width, .height]
  195. self.cancelButtonVC.stringValue = NSLocalizedString("Cancel", comment: "")
  196. self.cancelButtonVC.target = self
  197. self.cancelButtonVC.action = #selector(dismissSheet(_:))
  198. self.cancelButtonVC.button(type: .Sec_Icon, size: .m)
  199. self.clearButton.target = self
  200. self.clearButton.action = #selector(clearButton_Click(_:))
  201. self.clearButton.isHidden = true
  202. self.applyButton.title = ""
  203. self.applyButtonVC = KMDesignButton(withType: .Text)
  204. self.applyButton.addSubview(self.applyButtonVC.view)
  205. self.applyButtonVC.view.frame = self.applyButton.bounds
  206. self.applyButtonVC.view.autoresizingMask = [.width, .height]
  207. self.applyButtonVC.stringValue = NSLocalizedString("Save", comment: "")
  208. self.applyButtonVC.target = self
  209. self.applyButtonVC.action = #selector(applyButton_Click(_:))
  210. self.applyButtonVC.button(type: .Cta, size: .m)
  211. self.applyButtonVC.enabled = false
  212. self.contentBox.wantsLayer = true
  213. self.contentBox.layer?.backgroundColor = NSColor.clear.cgColor
  214. self.contentBox.borderType = .noBorder
  215. self.inputButton.isBordered = false
  216. self.drawingButton.isBordered = false
  217. self.pictureButton.isBordered = false
  218. // Keyboard
  219. self.inputView.wantsLayer = true
  220. self.inputView.layer?.backgroundColor = NSColor.white.cgColor
  221. self.keyboardView.wantsLayer = true
  222. self.keyboardView.layer?.backgroundColor = NSColor(red: 247/255.0, green: 248/255.0, blue: 250/255.0, alpha: 1.0).cgColor
  223. self.keyboardView.changeSignatureTextCallback = { isTrue in
  224. if isTrue {
  225. weakSelf?.clearButton.isHidden = false
  226. weakSelf?.clearButton.title = NSLocalizedString("Clear", comment: "")
  227. } else {
  228. weakSelf?.clearButton.isHidden = true
  229. }
  230. }
  231. keyboardColorBtn1.wantsLayer = true
  232. keyboardColorBtn2.wantsLayer = true
  233. keyboardColorBtn3.wantsLayer = true
  234. keyboardColorBtn4.wantsLayer = true
  235. keyboardColorBtn1.layer?.backgroundColor = NSColor(red: 0, green: 0, blue: 0, alpha: 1.0).cgColor
  236. keyboardColorBtn2.layer?.backgroundColor = NSColor(red: 252/255.0, green: 31/255.0, blue: 31/255.0, alpha: 1.0).cgColor
  237. keyboardColorBtn3.layer?.backgroundColor = NSColor(red: 39/255.0, green: 60/255.0, blue: 98/255.0, alpha: 1.0).cgColor
  238. keyboardColorBtn4.layer?.backgroundColor = NSColor(red: 148/255.0, green: 152/255.0, blue: 156/255.0, alpha: 1.0).cgColor
  239. let cornerRadius: CGFloat = 10.0
  240. keyboardColorBtn1.layer?.cornerRadius = cornerRadius
  241. keyboardColorBtn2.layer?.cornerRadius = cornerRadius
  242. keyboardColorBtn3.layer?.cornerRadius = cornerRadius
  243. keyboardColorBtn4.layer?.cornerRadius = cornerRadius
  244. keyboardColorBtn1.layer?.masksToBounds = true
  245. keyboardColorBtn2.layer?.masksToBounds = true
  246. keyboardColorBtn3.layer?.masksToBounds = true
  247. keyboardColorBtn4.layer?.masksToBounds = true
  248. keyboardColorSelView.wantsLayer = true
  249. keyboardColorSelView.layer?.backgroundColor = NSColor(red: 206/255.0, green: 208/255.0, blue: 212/255.0, alpha: 0.6).cgColor
  250. keyboardColorSelView.layer?.borderWidth = 1.0
  251. keyboardColorSelView.layer?.borderColor = NSColor(red: 206/255.0, green: 208/255.0, blue: 212/255.0, alpha: 1.0).cgColor
  252. keyboardColorSelView.layer?.cornerRadius = 4.0
  253. keyboardColorSelView.layer?.masksToBounds = true
  254. self.colorTextButtonAction(self.keyboardColorBtn1)
  255. // Draw
  256. self.drawView.delegate = self
  257. self.drawView.wantsLayer = true
  258. self.drawView.strokeRadius = CGFloat(((self.drawSizeDefaultValue as? NSString) ?? "0") .floatValue)
  259. self.drawView.layer?.cornerRadius = 4.0
  260. self.drawView.layer?.masksToBounds = true
  261. self.drawView.layer?.borderWidth = 1.0
  262. self.drawView.layer?.borderColor = NSColor(red: 223/255.0, green: 225/255.0, blue: 229/255.0, alpha: 1.0).cgColor
  263. self.drawView.layer?.backgroundColor = NSColor(red: 247/255.0, green: 248/255.0, blue: 250/255.0, alpha: 1.0).cgColor
  264. drawColorBtn1.wantsLayer = true
  265. drawColorBtn2.wantsLayer = true
  266. drawColorBtn3.wantsLayer = true
  267. drawColorBtn4.wantsLayer = true
  268. drawColorBtn1.layer?.backgroundColor = NSColor(red: 37/255.0, green: 38/255.0, blue: 41/255.0, alpha: 1.0).cgColor
  269. drawColorBtn2.layer?.backgroundColor = NSColor(red: 252/255.0, green: 31/255.0, blue: 31/255.0, alpha: 1.0).cgColor
  270. drawColorBtn3.layer?.backgroundColor = NSColor(red: 39/255.0, green: 60/255.0, blue: 98/255.0, alpha: 1.0).cgColor
  271. drawColorBtn4.layer?.backgroundColor = NSColor(red: 148/255.0, green: 152/255.0, blue: 156/255.0, alpha: 1.0).cgColor
  272. drawColorBtn1.layer?.cornerRadius = cornerRadius
  273. drawColorBtn2.layer?.cornerRadius = cornerRadius
  274. drawColorBtn3.layer?.cornerRadius = cornerRadius
  275. drawColorBtn4.layer?.cornerRadius = cornerRadius
  276. drawColorBtn1.layer?.masksToBounds = true
  277. drawColorBtn2.layer?.masksToBounds = true
  278. drawColorBtn3.layer?.masksToBounds = true
  279. drawColorBtn4.layer?.masksToBounds = true
  280. drawColorSelView.wantsLayer = true
  281. drawColorSelView.layer?.backgroundColor = NSColor(red: 206/255.0, green: 208/255.0, blue: 212/255.0, alpha: 0.6).cgColor
  282. drawColorSelView.layer?.borderWidth = 1.0
  283. drawColorSelView.layer?.borderColor = NSColor(red: 206/255.0, green: 208/255.0, blue: 212/255.0, alpha: 1.0).cgColor
  284. drawColorSelView.layer?.cornerRadius = 4.0
  285. drawColorSelView.layer?.masksToBounds = true
  286. self.drawColorBtnClicked(self.drawColorBtn1)
  287. for pxSize in ["0.5", "1.0", "1.5", "2.0", "2.5", "3.0"] {
  288. let attrited: [NSAttributedString.Key: Any] = [.font: NSFont.systemFont(ofSize: 14)]
  289. let string = NSAttributedString(string: pxSize, attributes: attrited)
  290. let item = NSMenuItem()
  291. item.attributedTitle = string
  292. self.drawSizeBox.menu?.addItem(item)
  293. }
  294. self.drawSizeBox.selectItem(at: 1)
  295. self.drawSizeBox.title = "1.0 pt"
  296. // Picture
  297. self.pictureView.wantsLayer = true
  298. self.pictureView.layer?.backgroundColor = NSColor.white.cgColor
  299. self.pictureBackView.wantsLayer = true
  300. self.pictureBackView.layer?.cornerRadius = 4.0
  301. self.pictureBackView.layer?.masksToBounds = true
  302. self.pictureBackView.layer?.borderWidth = 1.0
  303. self.pictureBackView.layer?.borderColor = NSColor(red: 223/255.0, green: 225/255.0, blue: 229/255.0, alpha: 1.0).cgColor
  304. self.pictureBackView.layer?.backgroundColor = NSColor(red: 247/255.0, green: 248/255.0, blue: 250/255.0, alpha: 1.0).cgColor
  305. self.pictureBackView.changeSignatureImageCallback = { isTrue in
  306. if isTrue {
  307. weakSelf?.applyButtonVC.enabled = true
  308. } else {
  309. weakSelf?.applyButtonVC.enabled = false
  310. }
  311. if let image = weakSelf?.pictureBackView.signatureImage {
  312. weakSelf?.clearButton.isHidden = false
  313. weakSelf?.clearButton.title = NSLocalizedString("Reselect", comment: "")
  314. } else {
  315. weakSelf?.clearButton.isHidden = true
  316. }
  317. }
  318. self.trackpadLabel.isHidden = true
  319. self.drawTipView.isHidden = true
  320. self.keyboardView.delegate = self
  321. self.drawView.changeDrawCallback = { isTrue in
  322. if isTrue {
  323. weakSelf?.applyButtonVC.enabled = true
  324. } else {
  325. weakSelf?.applyButtonVC.enabled = false
  326. }
  327. }
  328. self.drawView.touchEndCallback = { isClear in
  329. if isClear {
  330. weakSelf?.clearButton.isHidden = true
  331. } else {
  332. weakSelf?.clearButton.isHidden = false
  333. weakSelf?.clearButton.title = NSLocalizedString("Clear", comment: "")
  334. }
  335. }
  336. self.inputButton_Click(self.inputButton)
  337. self.pictureHelpButton.image = NSImage(named: "KMImageNameHelpNormal")
  338. self.pictureHelpButton.toolTip = "Remove white background from images"
  339. self.pictureHelpButton.action = #selector(showHelpTip(_:))
  340. self.pictureHelpButton.coverAction = { button, action in
  341. if action == .enter {
  342. button.image = NSImage(named: "KMImageNameHelpHover")
  343. // [weakSelf showHelpTip:button]
  344. } else if action == .exit {
  345. button.image = NSImage(named: "KMImageNameHelpNormal")
  346. // [weakSelf dismissHelpTip]
  347. }
  348. }
  349. localizedString()
  350. setupUI()
  351. }
  352. func setupUI() {
  353. let fontName = "SFProText-Regular"
  354. titleLabel.font = NSFont(name: "SFProText-Semibold", size: 16)
  355. titleLabel.textColor = NSColor(red: 37/255.0, green: 38/255.0, blue: 41/255.0, alpha: 1.0)
  356. signTypeView.wantsLayer = true
  357. signTypeView.layer?.backgroundColor = NSColor(red: 223/255.0, green: 225/255.0, blue: 229/255.0, alpha: 1.0).cgColor
  358. signTypeView.layer?.cornerRadius = 4.0
  359. signTypeView.layer?.masksToBounds = true
  360. signTypeBackView.wantsLayer = true
  361. signTypeBackView.layer?.cornerRadius = 2.0
  362. signTypeBackView.layer?.masksToBounds = true
  363. signTypeBackView.layer?.backgroundColor = NSColor.white.cgColor
  364. for button in [inputButton, drawingButton, pictureButton] {
  365. button?.setTitleColor(NSColor(red: 37/255.0, green: 38/255.0, blue: 41/255.0, alpha: 1.0))
  366. button?.font = NSFont(name: fontName, size: 12)
  367. }
  368. let fonts = CPDFAnnotationModel.supportFonts().compactMap { ($0 as AnyObject).allKeys.first }
  369. self.fontValues = fonts
  370. // Input
  371. fontVC = KMDesignSelect(withType: .Combox)
  372. fontBox.superview?.addSubview(fontVC.view)
  373. fontVC.view.translatesAutoresizingMaskIntoConstraints = false
  374. fontVC.view.leftAnchor.constraint(equalTo: fontBox.leftAnchor).isActive = true
  375. fontVC.view.centerYAnchor.constraint(equalTo: fontBox.centerYAnchor).isActive = true
  376. fontVC.view.widthAnchor.constraint(equalToConstant: 200).isActive = true
  377. fontBox.isHidden = true
  378. fontVC.delete = self
  379. fontVC.addItems(withObjectValues: fontValues)
  380. fontVC.stringValue = fontDefaultValue
  381. // Drawing
  382. drawSizeVC = KMDesignSelect(withType: .Combox)
  383. drawingView.addSubview(drawSizeVC.view)
  384. drawSizeVC.view.translatesAutoresizingMaskIntoConstraints = false
  385. drawSizeVC.view.leftAnchor.constraint(equalTo: drawSizeBox.leftAnchor).isActive = true
  386. drawSizeVC.view.centerYAnchor.constraint(equalTo: drawSizeBox.centerYAnchor).isActive = true
  387. drawSizeVC.view.widthAnchor.constraint(equalToConstant: 85).isActive = true
  388. drawSizeBox.isHidden = true
  389. drawSizeVC.delete = self
  390. var drawSizes = [String]()
  391. for value in drawSizeValues {
  392. drawSizes.append("\(value) pt")
  393. }
  394. drawSizeVC.addItems(withObjectValues: drawSizes)
  395. drawSizeVC.stringValue = "\(String(describing: drawSizeDefaultValue)) pt"
  396. trackpadButton.title = NSLocalizedString("Trackpad", comment: "")
  397. trackpadButton.setTitleColor(NSColor.clear)
  398. trackpadButtonVC = KMDesignButton(withType: .CheckBox)
  399. trackpadButton.addSubview(trackpadButtonVC.view)
  400. trackpadButtonVC.stringValue = NSLocalizedString("Trackpad", comment: "")
  401. trackpadButtonVC.state = .Norm
  402. trackpadButtonVC.checkbox_radio(imageHeight: NSLayoutConstraint())
  403. trackpadButtonVC.target = self
  404. trackpadButtonVC.action = #selector(trackpadButton_Click)
  405. var rect = trackpadButtonVC.view.frame
  406. rect.origin.y = rect.origin.y - 8
  407. trackpadButtonVC.view.frame = rect
  408. // trackpadButtonVC.view.translatesAutoresizingMaskIntoConstraints = false
  409. // trackpadButtonVC.view.leftAnchor.constraint(equalTo: trackpadButton.leftAnchor).isActive = true
  410. // trackpadButtonVC.view.centerYAnchor.constraint(equalTo: drawSizeVC.view.centerYAnchor).isActive = true
  411. // trackpadButtonVC.view.widthAnchor.constraint(equalToConstant: 120).isActive = true
  412. // trackpadButton.isHidden = true
  413. drawTipView.wantsLayer = true
  414. drawTipView.layer?.backgroundColor = NSColor(red: 189/255.0, green: 223/255.0, blue: 253/255.0, alpha: 1.0).cgColor
  415. drawTipLabel.stringValue = NSLocalizedString("Press any key to disable the touchpad", comment: "")
  416. drawTipLabel.textColor = NSColor(red: 37/255.0, green: 38/255.0, blue: 41/255.0, alpha: 1.0)
  417. drawTipLabel.font = NSFont(name: "SFProText-Regular", size: 14)
  418. // Picture
  419. pictureBackView.emptyTipLbl.textColor = NSColor(red: 148/255.0, green: 152/255.0, blue: 156/255.0, alpha: 1.0)
  420. pictureBackView.emptyTipLbl.font = NSFont(name: fontName, size: 14)
  421. pictureClearBackBtn.title = NSLocalizedString("Clear background", comment: "")
  422. pictureClearBackBtn.setTitleColor(.clear)
  423. pictureClearBackBtnVC = KMDesignButton(withType: .CheckBox)
  424. pictureClearBackBtn.addSubview(pictureClearBackBtnVC.view)
  425. pictureClearBackBtnVC.stringValue = NSLocalizedString("Clear background", comment: "")
  426. pictureClearBackBtnVC.state = .Norm
  427. pictureClearBackBtnVC.checkbox_radio(imageHeight: NSLayoutConstraint())
  428. pictureClearBackBtnVC.target = self
  429. pictureClearBackBtnVC.action = #selector(pictureClearBackBtnAction(_:))
  430. pictureClearBackBtnVC.view.translatesAutoresizingMaskIntoConstraints = false
  431. pictureClearBackBtnVC.view.mas_makeConstraints { make in
  432. make?.edges.equalTo()
  433. }
  434. }
  435. func setType(_ type: KMPDFSignatureType) {
  436. // self.type = type
  437. var rect = self.signTypeBackView.frame
  438. if type == .text {
  439. rect.origin.x = 1
  440. } else if type == .ink {
  441. rect.origin.x = 2 + 75
  442. } else if type == .image {
  443. rect.origin.x = 2 + 75 * 2
  444. }
  445. rect.origin.y = (self.signTypeBackView.superview!.frame.height - self.signTypeBackView.frame.height) / 2.0
  446. self.signTypeBackView.frame = rect
  447. self.clearButton.isHidden = true
  448. if type == .text {
  449. } else if type == .ink {
  450. } else if type == .image {
  451. if self.pictureBackView.signatureImage != nil {
  452. self.clearButton.title = NSLocalizedString("Reselect", comment: "")
  453. self.clearButton.isHidden = false
  454. }
  455. }
  456. }
  457. override func mouseDown(with event: NSEvent) {
  458. dismissHelpTip()
  459. }
  460. func localizedString() {
  461. self.titleLabel.stringValue = NSLocalizedString("Create Signature", comment: "")
  462. self.trackpadButton.title = (NSLocalizedString("Trackpad", comment: ""))
  463. self.clearButton.title = (NSLocalizedString("Clear", comment: ""))
  464. self.trackpadLabel.stringValue = NSLocalizedString("Press \"esc\" to disable the Trackpad.", comment: "")
  465. let selectorFonts = ["Mistral", "Bradley Hand", "Brush Script MT", "SignPainter", "Edwardian Script ITC", "American Typewriter", "Baoli SC", "Snell Roundhand", "Apple Chancery", "Monotype Corsiva"]
  466. let fonts = NSFontManager.shared.availableFontFamilies
  467. for fontName in fonts {
  468. let attributes: [NSAttributedString.Key: Any] = [.font: NSFont(name: fontName, size: 12.0)!]
  469. let attributedString = NSAttributedString(string: fontName, attributes: attributes)
  470. let item = NSMenuItem()
  471. item.attributedTitle = attributedString
  472. self.fontBox.menu?.addItem(item)
  473. }
  474. var fontName: String? = nil
  475. if recentlyFonts.count < 1 {
  476. for name in selectorFonts {
  477. if fonts.contains(name) {
  478. fontName = name
  479. break
  480. }
  481. }
  482. if let fontName = fontName {
  483. recentlyFonts.append(fontName)
  484. }
  485. } else {
  486. fontName = recentlyFonts.first
  487. }
  488. self.keyboardView.fontName = self.fontDefaultValue ?? ""
  489. for (index, fontName) in recentlyFonts.enumerated() {
  490. let attributes: [NSAttributedString.Key: Any] = [.font: NSFont(name: fontName, size: 12.0)!]
  491. let attributedString = NSAttributedString(string: fontName, attributes: attributes)
  492. let item = NSMenuItem()
  493. item.attributedTitle = attributedString
  494. self.fontBox.menu?.insertItem(item, at: 1 + index)
  495. }
  496. let sep = NSMenuItem.separator()
  497. self.fontBox.menu?.insertItem(sep, at: recentlyFonts.count + 1)
  498. self.selectItem = self.fontBox.menu?.item(at: 1)
  499. self.selectItem?.state = .on
  500. self.inputButton.title = NSLocalizedString("Keyboard", comment: "")
  501. self.drawingButton.title = NSLocalizedString("Trackpad", comment: "")
  502. self.pictureButton.title = NSLocalizedString("Image", comment: "")
  503. }
  504. @objc func showHelpTip(_ sender: NSButton) {
  505. if self.popover != nil {
  506. dismissHelpTip()
  507. return
  508. }
  509. let pop = NSPopover()
  510. self.popover = pop
  511. let controller = KMSignatureHelpViewController()
  512. pop.contentViewController = controller
  513. controller.tipString = NSLocalizedString("Remove white background from images", comment: "")
  514. pop.setValue(true, forKey: "shouldHideAnchor")
  515. pop.show(relativeTo: NSMakeRect(0, -8, sender.bounds.width, sender.bounds.height), of: sender, preferredEdge: .maxY)
  516. }
  517. func dismissHelpTip() {
  518. self.popover?.close()
  519. self.popover = nil
  520. }
  521. @IBAction func inputButton_Click(_ sender: Any) {
  522. self.contentBox.contentView = self.inputView
  523. self.type = .text
  524. }
  525. @IBAction func drawingButton_Click(_ sender: Any) {
  526. self.contentBox.contentView = self.drawingView
  527. self.type = .ink
  528. }
  529. @IBAction func pictureButton_Click(_ sender: Any) {
  530. self.contentBox.contentView = self.pictureView
  531. self.type = .image
  532. }
  533. @objc func clearButton_Click(_ sender: Any) {
  534. if self.type == .image {
  535. self.pictureBackView.reSelectImage()
  536. } else if self.type == .ink {
  537. self.drawView.clearImage()
  538. } else if self.type == .text {
  539. self.keyboardView.clearImage()
  540. }
  541. self.applyButtonVC.enabled = false
  542. }
  543. @objc func applyButton_Click(_ sender: Any) {
  544. let signature = KMSignature()
  545. if self.type == .text {
  546. if let image = self.keyboardView.signatureImage() {
  547. signature.pathsImage = image
  548. signature.signatureType = .text
  549. let signatureManager = KMSignatureManager()
  550. signatureManager.loadAllSignatureList()
  551. signatureManager.addSignature(signature)
  552. signatureManager.saveSingaturesToFile()
  553. } else {
  554. let alert = NSAlert()
  555. alert.alertStyle = .critical
  556. alert.messageText = NSLocalizedString("Unable to add new signatures. Please try again.", comment: "")
  557. alert.runModal()
  558. return
  559. }
  560. } else if self.type == .image {
  561. if let image = self.pictureBackView.signatureImage() {
  562. signature.pathsImage = image
  563. signature.signatureType = .image
  564. let signatureManager = KMSignatureManager()
  565. signatureManager.loadAllSignatureList()
  566. signatureManager.addSignature(signature)
  567. signatureManager.saveSingaturesToFile()
  568. } else {
  569. let alert = NSAlert()
  570. alert.alertStyle = .critical
  571. alert.messageText = NSLocalizedString("Unable to add new signatures. Please try again.", comment: "")
  572. alert.runModal()
  573. return
  574. }
  575. } else {
  576. if let image = self.drawView.signatureImage() {
  577. signature.addPath(self.drawView.drawBezierPath)
  578. signature.signatureType = .ink
  579. signature.signatureColor = self.drawView.drawColor
  580. signature.pathsImage = image
  581. let signatureManager = KMSignatureManager()
  582. signatureManager.loadAllSignatureList()
  583. signatureManager.addSignature(signature)
  584. signatureManager.saveSingaturesToFile()
  585. } else {
  586. let alert = NSAlert()
  587. alert.alertStyle = .critical
  588. alert.messageText = NSLocalizedString("Unable to add new signatures. Please try again.", comment: "")
  589. alert.runModal()
  590. return
  591. }
  592. }
  593. self.selectedSignature = signature
  594. dismissSheet(nil)
  595. }
  596. @IBAction func trackpadButton_Click(_ sender: Any) {
  597. if self.trackpadButtonVC.state == .Checked {
  598. self.trackpadButtonVC.state = .Norm
  599. self.trackpadLabel.isHidden = true
  600. self.drawTipView.isHidden = true
  601. self.drawView.isAcceptsTouch = false
  602. } else {
  603. self.trackpadButtonVC.state = .Checked
  604. self.trackpadLabel.isHidden = true
  605. self.drawTipView.isHidden = false
  606. self.drawView.isAcceptsTouch = true
  607. DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
  608. self.drawTipView.isHidden = true
  609. }
  610. }
  611. }
  612. @IBAction func boxItemClicked_Font(_ sender: Any) {
  613. if let name = self.fontBox.selectedItem?.title {
  614. self.fontBox.title = name
  615. self.keyboardView.fontName = name
  616. if recentlyFonts.contains(name) {
  617. if let index = recentlyFonts.firstIndex(of: name) {
  618. recentlyFonts.remove(at: index)
  619. self.fontBox.menu?.removeItem(at: index + 1)
  620. }
  621. }
  622. if recentlyFonts.count > 0 {
  623. recentlyFonts.insert(name, at: 0)
  624. } else {
  625. recentlyFonts.append(name)
  626. }
  627. if recentlyFonts.count > 5 {
  628. recentlyFonts.removeLast()
  629. self.fontBox.menu?.removeItem(at: recentlyFonts.count)
  630. }
  631. let attributes: [NSAttributedString.Key: Any] = [.font: NSFont(name: name, size: 12.0)!]
  632. let attributedString = NSAttributedString(string: name, attributes: attributes)
  633. let item = NSMenuItem()
  634. item.attributedTitle = attributedString
  635. self.fontBox.menu?.insertItem(item, at: 1)
  636. self.selectItem?.state = .off
  637. self.selectItem = self.fontBox.menu?.item(at: 1)
  638. self.selectItem?.state = .on
  639. }
  640. }
  641. @IBAction func colorTextButtonAction(_ sender: Any) {
  642. if let button = sender as? NSButton {
  643. if button == self.keyboardColorBtn1 || button == self.keyboardColorBtn2 || button == self.keyboardColorBtn3 || button == self.keyboardColorBtn4 {
  644. if let color = NSColor(cgColor: button.layer!.backgroundColor!) {
  645. self.keyboardView.keyboardColor = color
  646. var rect = self.keyboardView.frame
  647. rect.origin.y = button.frame.midY - 16
  648. rect.origin.x = button.frame.midX - 16
  649. rect.size.width = 32
  650. rect.size.height = 32
  651. self.keyboardColorSelView.frame = rect
  652. }
  653. } else {
  654. NSColorPanel.shared.setTarget(self)
  655. NSColorPanel.shared.setAction(#selector(keyboardColorPanelColorDidChange(_:)))
  656. NSColorPanel.shared.orderFront(nil)
  657. }
  658. }
  659. }
  660. @IBAction func drawColorBtnClicked(_ sender: NSButton) {
  661. if sender == self.drawColorBtn1 || sender == self.drawColorBtn2 || sender == self.drawColorBtn3 || sender == self.drawColorBtn4 {
  662. if let color = NSColor(cgColor: sender.layer!.backgroundColor!) {
  663. self.drawView.drawColor = color
  664. var rect = self.drawColorSelView.frame
  665. rect.origin.y = sender.frame.midY - 16
  666. rect.origin.x = sender.frame.midX - 16
  667. rect.size.width = 32
  668. rect.size.height = 32
  669. self.drawColorSelView.frame = rect
  670. }
  671. }
  672. }
  673. @IBAction func drawSizeBtnClicked(_ sender: NSPopUpButton) {
  674. let name = self.drawSizeBox.selectedItem?.title
  675. self.drawSizeBox.title = name ?? ""
  676. let array = [0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
  677. let index = self.drawSizeBox.indexOfSelectedItem - 1
  678. self.drawView.strokeRadius = array[index]
  679. }
  680. @objc @IBAction func pictureClearBackBtnAction(_ sender: NSButton) {
  681. var clearBack = true
  682. if self.pictureClearBackBtnVC.state == .Checked {
  683. self.pictureClearBackBtnVC.state = .Norm
  684. clearBack = false
  685. } else {
  686. self.pictureClearBackBtnVC.state = .Checked
  687. clearBack = true
  688. }
  689. self.pictureBackView.clearBackground = clearBack
  690. }
  691. @objc func keyboardColorPanelColorDidChange(_ sender: Any) {
  692. self.textColorButton.layer?.borderColor = NSColor.clear.cgColor
  693. let color = NSColorPanel.shared.color
  694. let red = CGFloat(color.redComponent)
  695. let green = CGFloat(color.greenComponent)
  696. let blue = CGFloat(color.blueComponent)
  697. let alpha = CGFloat(color.alphaComponent)
  698. self.keyboardView.keyboardColor = color
  699. self.textColorButton.layer?.borderColor = NSColor(red: 33.0/255.0, green: 124.0/255.0, blue: 234.0/255.0, alpha: 1.0).cgColor
  700. }
  701. func drawViewDidFinishTouchMode(_ view: KMDrawView) {
  702. self.trackpadButtonVC.state = .Norm
  703. self.trackpadLabel.isHidden = true
  704. self.drawTipView.isHidden = true
  705. }
  706. func changeSignatureText(_ isTrue: Bool) {
  707. self.applyButtonVC.enabled = isTrue
  708. }
  709. @objc func didEndSheet(_ sheet: NSWindow?, returnCode: Int, contextInfo: UnsafeMutableRawPointer?) {
  710. if contextInfo != nil && self.handler != nil {
  711. self.handler!(self.selectedSignature)
  712. }
  713. }
  714. func beginSheetModal(for window: NSWindow?, completionHandler handler: ((KMSignature) -> Void)?) {
  715. windowController_signature = self
  716. if window != nil {
  717. window!.beginSheet(self.window!) { ModalResponse in
  718. if self.selectedSignature != nil {
  719. self.handler?(self.selectedSignature)
  720. }
  721. }
  722. }
  723. self.handler = handler
  724. }
  725. @objc func dismissSheet(_ sender: Any?) {
  726. windowController_signature = nil
  727. if sender != nil {
  728. NSApp.endSheet(self.window!, returnCode: 0)
  729. } else {
  730. NSApp.endSheet(self.window!, returnCode: 1)
  731. }
  732. self.window?.orderOut(self)
  733. }
  734. func km_comboBoxSelectionDidChange(_ obj: KMDesignSelect) {
  735. if obj == fontVC {
  736. var index = fontVC.indexOfSelectedItem
  737. if index < 0 {
  738. index = 0
  739. }
  740. keyboardView.fontName = fontVC.items[index]
  741. } else if obj == drawSizeVC {
  742. var index = drawSizeVC.indexOfSelectedItem
  743. if index < 0 {
  744. index = 0
  745. }
  746. drawView.strokeRadius = CGFloat((drawSizeValues[index] as! NSString).floatValue)
  747. }
  748. }
  749. func tabView(_ tabView: NSTabView, shouldSelect tabViewItem: NSTabViewItem?) -> Bool {
  750. return true
  751. }
  752. func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) {
  753. var isImage = false
  754. if tabView.indexOfTabViewItem(tabViewItem!) == 0 {
  755. self.type = .text
  756. if self.keyboardView.signatureImage() != nil {
  757. isImage = true
  758. }
  759. } else if tabView.indexOfTabViewItem(tabViewItem!) == 1 {
  760. self.type = .ink
  761. if self.drawView.signatureImage() != nil {
  762. isImage = true
  763. }
  764. } else if tabView.indexOfTabViewItem(tabViewItem!) == 2 {
  765. self.type = .image
  766. if self.pictureBackView.signatureImage() != nil {
  767. isImage = true
  768. }
  769. }
  770. if isImage {
  771. self.applyButtonVC.enabled = true
  772. } else {
  773. self.applyButtonVC.enabled = false
  774. }
  775. }
  776. }