KMGeneralAnnotationViewController.swift 112 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394
  1. //
  2. // KMGeneralAnnotationViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by wanjun on 2023/12/1.
  6. //
  7. import Cocoa
  8. /**
  9. NSString *SKNFreeTextString = @"FreeText";
  10. NSString *SKNTextString = @"Text";
  11. NSString *SKNNoteString = @"Note";
  12. NSString *SKNCircleString = @"Circle";
  13. NSString *SKNSquareString = @"Square";
  14. NSString *SKNMarkUpString = @"MarkUp";
  15. NSString *SKNHighlightString = @"Highlight";
  16. NSString *SKNUnderlineString = @"Underline";
  17. NSString *SKNStrikeOutString = @"StrikeOut";
  18. NSString *SKNLineString = @"Line";
  19. NSString *SKNInkString = @"Ink";
  20. NSString *SKNPDFAnnotationTypeKey = @"type";
  21. NSString *SKNPDFAnnotationBoundsKey = @"bounds";
  22. NSString *SKNPDFAnnotationPageKey = @"page";
  23. NSString *SKNPDFAnnotationPageIndexKey = @"pageIndex";
  24. NSString *SKNPDFAnnotationContentsKey = @"contents";
  25. NSString *SKNPDFAnnotationStringKey = @"string";
  26. NSString *SKNPDFAnnotationColorKey = @"color";
  27. NSString *SKNPDFAnnotationBorderKey = @"border";
  28. NSString *SKNPDFAnnotationLineWidthKey = @"lineWidth";
  29. NSString *SKNPDFAnnotationBorderStyleKey = @"borderStyle";
  30. NSString *SKNPDFAnnotationDashPatternKey = @"dashPattern";
  31. NSString *SKNPDFAnnotationModificationDateKey = @"modificationDate";
  32. NSString *SKNPDFAnnotationUserNameKey = @"userName";
  33. NSString *SKNPDFAnnotationInteriorColorKey = @"interiorColor";
  34. NSString *SKNPDFAnnotationStartLineStyleKey = @"startLineStyle";
  35. NSString *SKNPDFAnnotationEndLineStyleKey = @"endLineStyle";
  36. NSString *SKNPDFAnnotationStartPointKey = @"startPoint";
  37. NSString *SKNPDFAnnotationEndPointKey = @"endPoint";
  38. NSString *SKNPDFAnnotationFontKey = @"font";
  39. NSString *SKNPDFAnnotationFontColorKey = @"fontColor";
  40. NSString *SKNPDFAnnotationFontNameKey = @"fontName";
  41. NSString *SKNPDFAnnotationFontSizeKey = @"fontSize";
  42. NSString *SKNPDFAnnotationAlignmentKey = @"alignment";
  43. NSString *SKNPDFAnnotationRotationKey = @"rotation";
  44. NSString *SKNPDFAnnotationQuadrilateralPointsKey = @"quadrilateralPoints";
  45. NSString *SKNPDFAnnotationIconTypeKey = @"iconType";
  46. NSString *SKNPDFAnnotationPointListsKey = @"pointLists";
  47. */
  48. enum KMActiveAnnotationType: UInt {
  49. case highlight = 0
  50. case strikeOut
  51. case underline
  52. case inkAndLine
  53. case text
  54. case squareAndCircle
  55. case freeText
  56. case selfSignFreeText
  57. }
  58. enum KMFreeTextAnnotationAlignmentType: UInt {
  59. case left = 0
  60. case center
  61. case right
  62. }
  63. let KMColorPickerViewHeight: CGFloat = 64
  64. @objcMembers class KMGeneralAnnotationViewController: NSViewController, NSTextViewDelegate {
  65. var _annotations: [CPDFAnnotation]?
  66. var subType: KMSelfSignAnnotationFreeTextSubType = .none
  67. var _activeAnnotationType: KMActiveAnnotationType = .highlight
  68. var pdfView: CPDFListView?
  69. var annotationModel: CPDFAnnotationModel?
  70. // var annotationCallback: ((CPDFAnnotation) -> Void)?
  71. @IBOutlet private weak var imageBox: NSBox!
  72. @IBOutlet private weak var imageBoxLayoutConstraint: NSLayoutConstraint!
  73. @IBOutlet private weak var textImageBoxView: NSView!
  74. @IBOutlet private weak var textImageBox: KMBox!
  75. @IBOutlet private weak var textAnnotationImageView: NSImageView!
  76. @IBOutlet private weak var textImageBoxButton: NSButton!
  77. @IBOutlet private weak var textImageUpDateButton: NSButton!
  78. @IBOutlet private weak var generalImageBoxView: NSView!
  79. @IBOutlet private weak var generalImageView: NSImageView!
  80. @IBOutlet private weak var fontView: NSView! // 字体
  81. @IBOutlet private weak var fontLabel: NSTextField!
  82. @IBOutlet private weak var fontButton: NSButton!
  83. @IBOutlet private weak var fontPopUpButton: KMPopUpButton!
  84. @IBOutlet private weak var fontSizeComboBox: KMComboBox!
  85. @IBOutlet private weak var fontStylePopUpButton: KMPopUpButton!
  86. @IBOutlet private weak var leftAlignButton: NSButton!
  87. @IBOutlet private weak var centerAlignButton: NSButton!
  88. @IBOutlet private weak var rightAlignButton: NSButton!
  89. @IBOutlet private weak var fontViewTopConstant: NSLayoutConstraint!
  90. @IBOutlet private weak var fontViewCorloPV: KMColorPickerView!
  91. @IBOutlet private weak var fontViewColorPVConstraint: NSLayoutConstraint!
  92. @IBOutlet private weak var rotateView: NSView! // 旋转
  93. @IBOutlet private weak var rotateLabel: NSTextField!
  94. @IBOutlet private weak var leftRotateBox: KMBox!
  95. @IBOutlet private weak var leftRotateButton: NSButton!
  96. @IBOutlet private weak var rightRotateBox: KMBox!
  97. @IBOutlet private weak var rightRotateButton: NSButton!
  98. @IBOutlet private weak var rotateViewTopConstant: NSLayoutConstraint!
  99. @IBOutlet private weak var typeView: NSView! // 类型
  100. @IBOutlet private weak var typeLabel: NSTextField!
  101. @IBOutlet private weak var tureTypeButton: NSButton!
  102. @IBOutlet private weak var falseTypeButton: NSButton!
  103. @IBOutlet private weak var circletypeButton: NSButton!
  104. @IBOutlet private weak var lineTypeButton: NSButton!
  105. @IBOutlet private weak var dotTypeButton: NSButton!
  106. @IBOutlet private weak var typeViewTopConstant: NSLayoutConstraint!
  107. @IBOutlet private weak var dateView: NSView! // 日期
  108. @IBOutlet private weak var dateLabel: NSTextField!
  109. @IBOutlet private weak var datePopUpButton: KMPopUpButton!
  110. @IBOutlet private weak var dateCheckButton: NSButton!
  111. @IBOutlet private weak var dateViewTopConstant: NSLayoutConstraint!
  112. @IBOutlet private weak var iconView: NSView! // 图标
  113. @IBOutlet private weak var iconLabel: NSTextField!
  114. @IBOutlet private weak var commentBox: NSBox!
  115. @IBOutlet private weak var commentButton: NSButton!
  116. @IBOutlet private weak var noteBox: NSBox!
  117. @IBOutlet private weak var noteButton: NSButton!
  118. @IBOutlet private weak var keyBox: NSBox!
  119. @IBOutlet private weak var keyButton: NSButton!
  120. @IBOutlet private weak var helpBox: NSBox!
  121. @IBOutlet private weak var helpButton: NSButton!
  122. @IBOutlet private weak var paragraphBox: NSBox!
  123. @IBOutlet private weak var paragraphButton: NSButton!
  124. @IBOutlet private weak var insertBox: NSBox!
  125. @IBOutlet private weak var insertButton: NSButton!
  126. @IBOutlet private weak var addParagraphBox: NSBox!
  127. @IBOutlet private weak var addParagraphButton: NSButton!
  128. @IBOutlet private weak var iconViewTopConstant: NSLayoutConstraint!
  129. @IBOutlet private weak var iconButtonHeightConstant: NSLayoutConstraint!
  130. @IBOutlet private weak var borderAndLineView: NSView! // 边框
  131. @IBOutlet private weak var borderLabel: NSTextField!
  132. @IBOutlet private weak var borderButton: NSButton!
  133. @IBOutlet private weak var lineWidthComboBox: KMComboBox!
  134. @IBOutlet private weak var lineWidthSlider: NSSlider!
  135. @IBOutlet private weak var lineTypeLabel: NSTextField!
  136. @IBOutlet private weak var lineStyleButton: KMButton!
  137. @IBOutlet private weak var dottedLineStyleButton: KMButton!
  138. @IBOutlet private weak var rightArrowStyleButton: KMButton!
  139. @IBOutlet private weak var lineStyleBox: NSBox!
  140. @IBOutlet private weak var dottedLineStyleBox: NSBox!
  141. @IBOutlet private weak var rightArrowStyleBox: NSBox!
  142. @IBOutlet private weak var borderViewTopConstant: NSLayoutConstraint!
  143. @IBOutlet private weak var fillColorView: NSView!
  144. @IBOutlet private weak var fillColorLabel: NSTextField!
  145. @IBOutlet private weak var fillColorPickerView: KMColorPickerView!
  146. @IBOutlet private weak var fillColorViewTopConstraint: NSLayoutConstraint!
  147. @IBOutlet private weak var opacityView: NSView! // 透明度
  148. @IBOutlet private weak var opacityLabel: NSTextField!
  149. @IBOutlet private weak var opacitySlider: NSSlider!
  150. @IBOutlet private weak var opacityComboBox: KMComboBox!
  151. @IBOutlet private weak var opacityViewTopConstant: NSLayoutConstraint!
  152. @IBOutlet private weak var noteView: NSView! // 笔记
  153. @IBOutlet private weak var noteViewLabel: NSTextField!
  154. @IBOutlet private var noteTextView: NSTextView!
  155. @IBOutlet private weak var noteViewTopConstant: NSLayoutConstraint!
  156. @IBOutlet private weak var colorView: NSView! // 颜色
  157. @IBOutlet private weak var colorTitleLabel: NSTextField!
  158. @IBOutlet private weak var textColorBox: NSBox!
  159. @IBOutlet private weak var textColorBoxConstraint: NSLayoutConstraint!
  160. @IBOutlet private weak var textColorPickerView: KMColorPickerView!
  161. @IBOutlet private weak var borderColorBox: NSBox!
  162. @IBOutlet private weak var borderColorPickerView: KMColorPickerView!
  163. @IBOutlet private weak var borderColorBoxConstraint: NSLayoutConstraint!
  164. @IBOutlet private weak var lineWidthBox: NSBox!
  165. @IBOutlet private weak var widthLabel: NSTextField!
  166. @IBOutlet private weak var widthComboBox: KMComboBox!
  167. @IBOutlet private weak var widthSlider: NSSlider!
  168. @IBOutlet private weak var ColorViewTopConstant: NSLayoutConstraint!
  169. @IBOutlet private weak var textColorPickerViewConstant: NSLayoutConstraint!
  170. var isannotationMode: Bool = false
  171. var selectedAlignmentButtonLayer: CALayer?
  172. var iconButtonArray: [NSBox] = []
  173. var lineStyleCount: Int = 0
  174. var isTextEdit: Bool = false
  175. var fonts: [[String : [String]]]!
  176. var annotationAlignment: KMFreeTextAnnotationAlignmentType = .left
  177. var noteIcons: [NSImage?] = [nil, nil, nil, nil, nil, nil, nil]
  178. private func makeNoteIcons() {
  179. if noteIcons[0] != nil { return }
  180. let bounds = CGRect(origin: .zero, size: NSMakeSize(16, 16))
  181. let annotation = CPDFTextAnnotation()
  182. annotation.bounds = bounds
  183. annotation.color = NSColor.clear
  184. let page = CPDFPage()
  185. page.setBounds(bounds, for: .mediaBox)
  186. page.addAnnotation(annotation)
  187. for i in 0..<7 {
  188. annotation.setIconType(CPDFTextAnnotationIconType(rawValue: i) ?? .comment)
  189. noteIcons[i] = NSImage.bitmapImage(with: NSMakeSize(16, 16), drawingHandler: { rect in
  190. page.draw(with: .mediaBox, to: (NSGraphicsContext.current?.cgContext))
  191. })
  192. }
  193. }
  194. deinit {
  195. NotificationCenter.default.removeObserver(self)
  196. DistributedNotificationCenter.default().removeObserver(self)
  197. if ((annotationModel?.annotation) != nil) && annotationModel?.annotations.count == 1 {
  198. let keys = ["contents", "markupText"]
  199. for key in keys {
  200. annotationModel?.annotation.removeObserver(self, forKeyPath: key)
  201. }
  202. }
  203. textColorPickerView.target = nil
  204. textColorPickerView.action = nil
  205. borderColorPickerView.target = nil
  206. borderColorPickerView.action = nil
  207. fillColorPickerView.target = nil
  208. fillColorPickerView.action = nil
  209. NSColorPanel.shared.setTarget(nil)
  210. NSColorPanel.shared.setAction(nil)
  211. }
  212. // MARK: View Methods
  213. override func loadView() {
  214. super.loadView()
  215. DispatchQueue.main.async {
  216. if NSColorPanel.shared.isVisible {
  217. NSColorPanel.shared.close()
  218. }
  219. }
  220. isannotationMode = true
  221. fonts = (CPDFAnnotationModel.supportFonts() as! [[String : [String]]])
  222. imageBox.borderColor = KMAppearance.Interactive.s0Color()
  223. imageBox.borderWidth = 1.0
  224. imageBox.fillColor = KMAppearance.Layout.l1Color()
  225. textImageBox.fillColor = KMAppearance.Layout.l1Color()
  226. fontLabel.stringValue = NSLocalizedString("Fonts", comment: "")
  227. fontLabel.textColor = KMAppearance.Layout.h0Color()
  228. colorTitleLabel.stringValue = NSLocalizedString("Color", comment: "")
  229. colorTitleLabel.textColor = KMAppearance.Layout.h0Color()
  230. opacityLabel.stringValue = NSLocalizedString("Opacity", comment: "")
  231. opacityLabel.textColor = KMAppearance.Layout.h1Color()
  232. noteViewLabel.stringValue = NSLocalizedString("Note", comment: "")
  233. noteViewLabel.textColor = KMAppearance.Layout.h0Color()
  234. rotateLabel.stringValue = NSLocalizedString("Rotate", comment: "")
  235. rotateLabel.textColor = KMAppearance.Layout.h0Color()
  236. typeLabel.stringValue = NSLocalizedString("Type", comment: "")
  237. typeLabel.textColor = KMAppearance.Layout.h0Color()
  238. dateLabel.stringValue = NSLocalizedString("Date", comment: "")
  239. dateLabel.textColor = KMAppearance.Layout.h0Color()
  240. iconLabel.stringValue = NSLocalizedString("Icon", comment: "")
  241. iconLabel.textColor = KMAppearance.Layout.h0Color()
  242. borderLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
  243. borderLabel.textColor = KMAppearance.Layout.h0Color()
  244. fillColorLabel.stringValue = NSLocalizedString("Fill", comment: "")
  245. fillColorLabel.textColor = KMAppearance.Layout.h0Color()
  246. lineStyleCount = 0
  247. if annotationType == .highlight {
  248. activeAnnotationType = .highlight
  249. } else if annotationType == .strikeOut {
  250. activeAnnotationType = .strikeOut
  251. } else if annotationType == .underline {
  252. activeAnnotationType = .underline
  253. } else if annotationType == .ink || annotationType == .line || annotationType == .arrow {
  254. activeAnnotationType = .inkAndLine
  255. } else if annotationType == .anchored {
  256. activeAnnotationType = .text
  257. } else if annotationType == .circle || annotationType == .square {
  258. borderColorPickerView.isCallColorPanelAction = isannotationMode
  259. textColorPickerView.isCallColorPanelAction = isannotationMode
  260. activeAnnotationType = .squareAndCircle
  261. } else if annotationType == .freeText {
  262. if subType == .date {
  263. colorTitleLabel.stringValue = NSLocalizedString("Fill Color", comment: "")
  264. activeAnnotationType = .selfSignFreeText
  265. } else {
  266. activeAnnotationType = .freeText
  267. }
  268. fontViewCorloPV.isCallColorPanelAction = isannotationMode
  269. var alignmentType: KMFreeTextAnnotationAlignmentType = .left
  270. if annotationModel?.alignment() == .left {
  271. alignmentType = .left
  272. } else if annotationModel?.alignment() == .center {
  273. alignmentType = .center
  274. } else if annotationModel?.alignment() == .right {
  275. alignmentType = .right
  276. }
  277. alignmentTypeSelected(alignmentType)
  278. }
  279. textColorPickerView.isCallColorPanelAction = isannotationMode
  280. borderColorPickerView.isCallColorPanelAction = isannotationMode
  281. if annotationType == .freeText {
  282. fontViewCorloPV.isFreeText = true
  283. } else {
  284. fontViewCorloPV.isFreeText = false
  285. }
  286. if annotationType == .ink || annotationType == .line || annotationType == .arrow || annotationType == .square || annotationType == .circle {
  287. let lineType = annotationModel?.style()
  288. if lineType == .dashed {
  289. let lineType = annotationModel?.dashPattern()
  290. // if lineType.count == 0 {
  291. // let number = NSNumber(value: Float(4))
  292. // annotation.setDashPattern([number])
  293. //
  294. // let userDefaults = UserDefaults.standard
  295. // if annotationType == .ink {
  296. // userDefaults.set(annotationModel?.dashPattern(), forKey: SKInkNoteDashPatternKey)
  297. // } else if annotationType == .line {
  298. // userDefaults.set(annotationModel?.dashPattern(), forKey: SKLineNoteDashPatternKey)
  299. // } else if annotationType == .square {
  300. // userDefaults.set(annotationModel?.dashPattern(), forKey: SKSquareNoteDashPatternKey)
  301. // } else if annotationType == .circle {
  302. // userDefaults.set(annotationModel?.dashPattern(), forKey: SKCircleNoteDashPatternKey)
  303. // } else if annotationType == .freeText {
  304. // userDefaults.set(annotationModel?.dashPattern(), forKey: CFreeTextNoteDashPatternKey)
  305. // }
  306. // }
  307. }
  308. }
  309. opacityComboBox.type = .none
  310. opacityComboBox.comboxRect = opacityComboBox.bounds
  311. lineWidthComboBox.type = .none
  312. lineWidthComboBox.comboxRect = lineWidthComboBox.bounds
  313. widthComboBox.type = .none
  314. widthComboBox.comboxRect = widthComboBox.bounds
  315. fontPopUpButton.type = .arrowDown
  316. fontSizeComboBox.type = .none
  317. fontSizeComboBox.comboxRect = fontSizeComboBox.bounds
  318. fontStylePopUpButton.type = .arrowUpDown
  319. datePopUpButton.type = .arrowUpDown
  320. noteTextView.backgroundColor = KMAppearance.Layout.l1Color()
  321. let views: [NSView] = [fontPopUpButton, fontSizeComboBox, fontStylePopUpButton, lineWidthComboBox, opacityComboBox, widthComboBox, datePopUpButton, noteTextView]
  322. for view in views {
  323. view.wantsLayer = true
  324. view.layer?.borderWidth = 1.0
  325. view.layer?.cornerRadius = 1.0
  326. }
  327. refreshLineTypeUI()
  328. rightArrowStyleButton.isHidden = true
  329. rightArrowStyleBox.isHidden = true
  330. annotationFontReload()
  331. reloadData()
  332. updateViewColor()
  333. if ((annotationModel?.annotation) != nil) && annotationModel?.annotations.count == 1 {
  334. let annotation = annotationModel?.annotation
  335. let keys = ["contents", "markupText"]
  336. for key in keys {
  337. annotation?.addObserver(self, forKeyPath: key, options: [.new, .old], context: nil)
  338. }
  339. }
  340. // NotificationCenter.default.addObserver(self, selector: #selector(alignmentTypeNotification(_:)), name: "KMAnnotationAlignmentTypeNotification1", object: nil)
  341. // NotificationCenter.default.addObserver(self, selector: #selector(loadingUIAndLocalization(_:)), name: "KMPreferenceDidChangeNotificationName", object: nil)
  342. // NotificationCenter.default.addObserver(self, selector: #selector(annotationChangeNotification(_:)), name: CPDFListViewAnnotationsAttributeHasChangeNotification, object: nil)
  343. }
  344. override func viewDidLoad() {
  345. super.viewDidLoad()
  346. // Do view setup here.
  347. }
  348. override func viewDidAppear() {
  349. super.viewDidAppear()
  350. let showConvertDetails = KMPropertiesViewPopController.showChangeColorDetails()
  351. let fileURL = (self.view.window?.windowController?.document as? NSDocument)?.fileURL
  352. if showConvertDetails && (fileURL != nil) {
  353. KMPropertiesViewPopController.defaultManager.showChangeColorDetailsView(self.textColorPickerView.firstButton)
  354. }
  355. DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil)
  356. }
  357. func reloadData() {
  358. var annotationColor = annotationModel?.color()
  359. if annotationType == .signFalse ||
  360. annotationType == .signTure ||
  361. annotationType == .signDot ||
  362. annotationType == .signCircle ||
  363. annotationType == .signLine {
  364. annotationColor = annotationModel?.color()
  365. } else if annotationType == .square ||
  366. annotationType == .circle {
  367. annotationColor = annotationModel?.color()
  368. } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
  369. annotationColor = annotationModel?.interiorColor()
  370. } else {
  371. annotationColor = annotationModel?.color()
  372. }
  373. let color = annotationColor ?? NSColor.black
  374. // guard let color = annotationColor else { return }
  375. var opacity: CGFloat = 1.0
  376. color.usingColorSpaceName(.calibratedRGB)?.getRed(nil, green: nil, blue: nil, alpha: &opacity)
  377. if annotationType == .signFalse ||
  378. annotationType == .signTure ||
  379. annotationType == .signDot ||
  380. annotationType == .signCircle ||
  381. annotationType == .signLine {
  382. opacity = (annotationModel?.opacity())!
  383. } else if annotationType == .square ||
  384. annotationType == .circle {
  385. opacity = (annotationModel?.opacity())!
  386. } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
  387. opacity = (annotationModel?.interiorOpacity())!
  388. } else {
  389. opacity = (annotationModel?.opacity())!
  390. }
  391. opacitySlider.floatValue = Float(opacity)
  392. opacitySlider.toolTip = "\(Int(opacity * 100))%"
  393. opacityComboBox.stringValue = "\(Int(opacity * 100))%"
  394. if annotationModel?.annotations != nil {
  395. let contextString = annotation.string() ?? ""
  396. noteTextView.string = contextString
  397. noteTextView.textColor = NSColor.labelColor
  398. noteTextView.delegate = self
  399. }
  400. if annotationType == .freeText {
  401. imageBox.contentView = textImageBoxView
  402. textAnnotationImageView.image = annotationModel?.annotationImage
  403. } else if annotationType == .signText || annotationType == .signDate {
  404. imageBox.contentView = generalImageBoxView
  405. generalImageView.image = annotationModel?.annotationImage
  406. } else {
  407. imageBox.contentView = generalImageBoxView
  408. generalImageView.image = annotationModel?.annotationImage
  409. }
  410. if annotationType == .square || annotationType == .circle || annotationType == .line || annotationType == .arrow || annotationType == .ink {
  411. if annotationType == .ink {
  412. textColorPickerView.setColor(color)
  413. } else if annotationType == .square || annotationType == .circle {
  414. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  415. let modelColor = annotationModel?.interiorColor() ?? .black
  416. modelColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  417. let interiorColor = NSColor(red: red, green: green, blue: blue, alpha: (annotationModel?.interiorOpacity())!)
  418. textColorPickerView.setColor(interiorColor)
  419. textColorPickerView.isFillColor = true
  420. borderColorPickerView.setColor(color)
  421. } else if annotationType == .line || annotationType == .arrow {
  422. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  423. let modelColor = annotationModel?.interiorColor() ?? .black
  424. modelColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  425. let interiorColor = NSColor(red: red, green: green, blue: blue, alpha: (annotationModel?.interiorOpacity())!)
  426. textColorPickerView.setColor(interiorColor)
  427. textColorPickerView.isFillColor = true
  428. borderColorPickerView.setColor(color)
  429. }
  430. lineWidthSlider.floatValue = Float(annotationModel?.lineWidth() ?? 1.0)
  431. lineWidthSlider.toolTip = "\(annotationModel?.lineWidth() ?? 1.0) pt"
  432. lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  433. } else if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  434. if annotationType == .signText || annotationType == .signDate {
  435. if subType == .date {
  436. dateView.isHidden = false
  437. datePopUpButton.removeAllItems()
  438. let freeText = annotation as! KMSelfSignAnnotationFreeText
  439. // self.datePopUpButton.addItems(withTitles: KMSelfSignAnnotationFreeText.fetchAllDateString(includeTime: <#T##Bool#>))
  440. if freeText.dateFormatIndex >= 0, freeText.dateFormatIndex < datePopUpButton.numberOfItems {
  441. datePopUpButton.selectItem(at: freeText.dateFormatIndex)
  442. } else {
  443. datePopUpButton.selectItem(at: 0)
  444. }
  445. dateCheckButton.state = freeText.includeTime ? NSControl.StateValue.on : NSControl.StateValue.off
  446. textColorPickerView.setColor(annotation.color)
  447. }
  448. } else {
  449. lineWidthSlider.minValue = 0.0
  450. lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
  451. lineWidthSlider.toolTip = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  452. lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  453. var alignmentType: KMFreeTextAnnotationAlignmentType = .left
  454. if annotationModel?.alignment() == .left {
  455. alignmentType = .left
  456. } else if annotationModel?.alignment() == .center {
  457. alignmentType = .center
  458. } else if annotationModel?.alignment() == .right {
  459. alignmentType = .right
  460. }
  461. alignmentTypeSelected(alignmentType)
  462. annotationFontReload()
  463. fillColorPickerView.color = annotationModel?.color()
  464. }
  465. fontViewCorloPV.color = annotationModel?.fontColor()
  466. fontSizeComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.fontSize())!)
  467. } else if annotationType == .highlight || annotationType == .strikeOut || annotationType == .underline || annotationType == .anchored {
  468. textColorPickerView.setColor(color)
  469. }
  470. noteView.isHidden = isannotationMode
  471. if annotationType == .signText || annotationType == .signDate {
  472. if subType == .date {
  473. noteView.isHidden = true
  474. } else {
  475. noteView.isHidden = false
  476. }
  477. }
  478. if annotationModel?.annotations != nil {
  479. noteView.isHidden = annotationModel?.annotation==nil
  480. } else {
  481. if annotationType == .stamp ||
  482. annotationType == .ink ||
  483. annotationType == .square ||
  484. annotationType == .circle ||
  485. annotationType == .arrow ||
  486. annotationType == .line ||
  487. annotationType == .highlight ||
  488. annotationType == .strikeOut ||
  489. annotationType == .underline ||
  490. annotationType == .freeText {
  491. noteView.isHidden = true
  492. } else {
  493. noteView.isHidden = annotationModel?.annotation==nil
  494. }
  495. }
  496. }
  497. // MARK: Set & Get
  498. var annotations: [CPDFAnnotation] {
  499. get {
  500. return annotationModel?.annotations as? [CPDFAnnotation] ?? []
  501. }
  502. }
  503. var annotation: CPDFAnnotation {
  504. get {
  505. return annotationModel?.annotation ?? CPDFAnnotation()
  506. }
  507. }
  508. var annotationType: CAnnotationType {
  509. get {
  510. return (annotationModel?.annotationType as? CAnnotationType)!
  511. }
  512. }
  513. func updateannotationMode() {
  514. let defaults = UserDefaults.standard
  515. if annotationType == .freeText {
  516. // if ([annotation isKindOfClass:[SKNPDFAnnotationNote class]]) {
  517. // [sud setColor:self.annotation.color forKey:SKNPDFAnnotationColorKey];
  518. // [sud setInteger:self.annotation.iconType forKey:SKAnchoredNoteIconTypeKey];
  519. // }
  520. if annotation.isKind(of: CPDFFreeTextAnnotation.self) {
  521. defaults.safe_setColor(annotation.color, forKey: CFreeTextNoteColorKey)
  522. defaults.safe_setColor((annotation as! CPDFFreeTextAnnotation).fontColor, forKey: CFreeTextNoteFontColorKey)
  523. defaults.set((annotation as! CPDFFreeTextAnnotation).alignment.rawValue, forKey: CFreeTextNoteAlignmentKey)
  524. defaults.set((annotation as! CPDFFreeTextAnnotation).fontName(), forKey: CFreeTextNoteFontNameKey)
  525. defaults.set((annotation as! CPDFFreeTextAnnotation).fontSize(), forKey: CFreeTextNoteFontSizeKey)
  526. defaults.set(annotation.lineWidth(), forKey: CFreeTextNoteLineWidthKey)
  527. defaults.set(annotation.borderStyle().rawValue, forKey: CFreeTextNoteLineStyleKey)
  528. defaults.set(annotation.dashPattern(), forKey: CFreeTextNoteDashPatternKey)
  529. }
  530. } else if annotationType == .circle {
  531. defaults.safe_setColor(annotation.color, forKey: CCircleNoteColorKey)
  532. defaults.safe_setColor((annotation as! CPDFCircleAnnotation).interiorColor, forKey: CCircleNoteInteriorColorKey)
  533. defaults.set(annotation.lineWidth(), forKey: CCircleNoteLineWidthKey)
  534. defaults.set((annotation as! CPDFCircleAnnotation).borderStyle().rawValue, forKey: CCircleNoteLineStyleKey)
  535. defaults.set((annotation as! CPDFCircleAnnotation).dashPattern(), forKey: CCircleNoteDashPatternKey)
  536. } else if annotationType == .square {
  537. defaults.safe_setColor(annotation.color, forKey: CSquareNoteColorKey)
  538. defaults.safe_setColor((annotation as! CPDFSquareAnnotation).interiorColor, forKey: CSquareNoteInteriorColorKey)
  539. defaults.set(annotation.lineWidth(), forKey: CSquareNoteLineWidthKey)
  540. defaults.set((annotation as! CPDFSquareAnnotation).borderStyle().rawValue, forKey: CSquareNoteLineStyleKey)
  541. defaults.set((annotation as! CPDFSquareAnnotation).dashPattern(), forKey: CSquareNoteDashPatternKey)
  542. } else if annotationType == .highlight {
  543. defaults.safe_setColor(annotation.color, forKey: CHighlightNoteColorKey)
  544. } else if annotationType == .underline {
  545. defaults.safe_setColor(annotation.color, forKey: CUnderlineNoteColorKey)
  546. } else if annotationType == .strikeOut {
  547. defaults.safe_setColor(annotation.color, forKey: CStrikeOutNoteColorKey)
  548. } else if annotationType == .line || annotationType == .arrow {
  549. defaults.safe_setColor(annotation.color, forKey: CLineNoteColorKey)
  550. defaults.set(annotation.lineWidth(), forKey: CLineNoteLineWidthKey)
  551. defaults.set(annotation.borderStyle().rawValue, forKey: CLineNoteLineStyleKey)
  552. defaults.set(annotation.dashPattern(), forKey: CLineNoteDashPatternKey)
  553. defaults.safe_setColor((annotation as! CPDFLineAnnotation).interiorColor, forKey: CLineNoteInteriorColorKey)
  554. defaults.set((annotation as! CPDFLineAnnotation).startLineStyle.rawValue, forKey: CLineNoteStartLineStyleKey)
  555. defaults.set((annotation as! CPDFLineAnnotation).endLineStyle.rawValue, forKey: CLineNoteEndLineStyleKey)
  556. } else if annotationType == .ink {
  557. defaults.safe_setColor(annotation.color, forKey: CInkNoteColorKey)
  558. defaults.set(annotation.lineWidth(), forKey: CInkNoteLineWidthKey)
  559. defaults.set(annotation.borderStyle().rawValue, forKey: CInkNoteLineStyleKey)
  560. defaults.set(annotation.dashPattern(), forKey: CInkNoteDashPatternKey)
  561. } else if annotationType == .anchored {
  562. // [sud setColor:self.annotation.color forKey:SKNPDFAnnotationColorKey];
  563. // [sud setInteger:self.annotation.iconType forKey:SKAnchoredNoteIconTypeKey];
  564. }
  565. }
  566. var activeAnnotationType: KMActiveAnnotationType {
  567. set {
  568. _activeAnnotationType = newValue
  569. switch self.activeAnnotationType {
  570. case .highlight, .strikeOut, .underline:
  571. self.fontView.isHidden = true
  572. self.borderAndLineView.isHidden = true
  573. self.fillColorView.isHidden = true
  574. self.rotateView.isHidden = true
  575. self.typeView.isHidden = true
  576. self.dateView.isHidden = true
  577. self.iconView.isHidden = true
  578. self.createMarkupProperties()
  579. case .inkAndLine:
  580. self.fontView.isHidden = true
  581. self.fillColorView.isHidden = true
  582. self.rotateView.isHidden = true
  583. self.typeView.isHidden = true
  584. self.dateView.isHidden = true
  585. self.iconView.isHidden = true
  586. self.createInkAndLineProperties()
  587. case .text:
  588. self.fontView.isHidden = true
  589. self.borderAndLineView.isHidden = true
  590. self.fillColorView.isHidden = true
  591. self.rotateView.isHidden = true
  592. self.typeView.isHidden = true
  593. self.dateView.isHidden = true
  594. self.createTextProperties()
  595. case .squareAndCircle:
  596. self.fontView.isHidden = true
  597. self.rotateView.isHidden = true
  598. self.typeView.isHidden = true
  599. self.dateView.isHidden = true
  600. self.iconView.isHidden = true
  601. self.fillColorView.isHidden = true
  602. self.createSquareAndCircleProperties()
  603. case .freeText:
  604. self.colorView.isHidden = true
  605. self.rotateView.isHidden = true
  606. self.typeView.isHidden = true
  607. self.dateView.isHidden = true
  608. self.iconView.isHidden = true
  609. self.createFreeTextProperties()
  610. case .selfSignFreeText:
  611. self.rotateView.isHidden = true
  612. self.borderAndLineView.isHidden = true
  613. self.fillColorView.isHidden = true
  614. self.typeView.isHidden = true
  615. self.iconView.isHidden = true
  616. self.createSelfSignFreeTextProperties()
  617. default:
  618. break
  619. }
  620. }
  621. get {
  622. return _activeAnnotationType
  623. }
  624. }
  625. // MARK: private
  626. func updateViewColor() {
  627. if KMAppearance.isDarkMode() {
  628. let darkColor = NSColor(red: 57/255.0, green: 60/255.0, blue: 62/255.0, alpha: 1.0).cgColor
  629. let borderColor = NSColor(red: 86/255.0, green: 88/255.0, blue: 90/255.0, alpha: 1.0).cgColor
  630. setViewColor(fontPopUpButton, darkColor, borderColor)
  631. setViewColor(fontSizeComboBox, darkColor, borderColor)
  632. setViewColor(fontStylePopUpButton, darkColor, borderColor)
  633. setViewColor(lineWidthComboBox, darkColor, borderColor)
  634. setViewColor(opacityComboBox, darkColor, borderColor)
  635. setViewColor(datePopUpButton, darkColor, borderColor)
  636. setViewColor(widthComboBox, darkColor, borderColor)
  637. setViewColor(noteTextView, darkColor, borderColor)
  638. } else {
  639. let lightColor = NSColor.white.cgColor
  640. let borderColor = NSColor(red: 218/255.0, green: 219/255.0, blue: 222/255.0, alpha: 1.0).cgColor
  641. setViewColor(fontPopUpButton, lightColor, borderColor)
  642. setViewColor(fontSizeComboBox, lightColor, borderColor)
  643. setViewColor(fontStylePopUpButton, lightColor, borderColor)
  644. setViewColor(lineWidthComboBox, lightColor, borderColor)
  645. setViewColor(opacityComboBox, lightColor, borderColor)
  646. setViewColor(datePopUpButton, lightColor, borderColor)
  647. setViewColor(widthComboBox, lightColor, borderColor)
  648. setViewColor(noteTextView, lightColor, borderColor)
  649. }
  650. }
  651. func setViewColor(_ view: NSView, _ backgroundColor: CGColor, _ borderColor: CGColor) {
  652. view.layer?.backgroundColor = backgroundColor
  653. view.layer?.borderColor = borderColor
  654. }
  655. func refreshLineTypeUI() {
  656. lineStyleBox.borderColor = KMAppearance.Interactive.s0Color()
  657. dottedLineStyleBox.borderColor = KMAppearance.Interactive.s0Color()
  658. rightArrowStyleBox.borderColor = KMAppearance.Interactive.s0Color()
  659. lineStyleBox.fillColor = KMAppearance.Layout.l1Color()
  660. dottedLineStyleBox.fillColor = KMAppearance.Layout.l1Color()
  661. rightArrowStyleBox.fillColor = KMAppearance.Layout.l1Color()
  662. lineStyleBox.borderWidth = 1
  663. dottedLineStyleBox.borderWidth = 1
  664. rightArrowStyleBox.borderWidth = 1
  665. if lineStyleCount == 0 {
  666. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  667. lineStyleBox.borderWidth = 0.0
  668. } else if lineStyleCount == 1 {
  669. dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
  670. dottedLineStyleBox.borderWidth = 0
  671. } else if lineStyleCount == 2 {
  672. rightArrowStyleBox.fillColor = KMAppearance.Status.selColor()
  673. rightArrowStyleBox.borderWidth = 0
  674. }
  675. }
  676. func hiddenSubviews() {
  677. fontViewTopConstant.constant = fontView.isHidden ? -(fontView.bounds.size.height) - 20 : 10
  678. ColorViewTopConstant.constant = colorView.isHidden ? -(colorView.bounds.size.height) : 10
  679. borderViewTopConstant.constant = borderAndLineView.isHidden ? -(borderAndLineView.bounds.size.height) : 20
  680. opacityViewTopConstant.constant = opacityView.isHidden ? -opacityView.bounds.size.height : 20
  681. rotateViewTopConstant.constant = rotateView.isHidden ? -(rotateView.bounds.size.height) : 20
  682. typeViewTopConstant.constant = typeView.isHidden ? -(typeView.bounds.size.height) : 20
  683. dateViewTopConstant.constant = dateView.isHidden ? -(dateView.bounds.size.height) : 20
  684. iconViewTopConstant.constant = iconView.isHidden ? -(iconView.bounds.size.height) : 20
  685. noteViewTopConstant.constant = noteView.isHidden ? -(noteView.bounds.size.height) : 20
  686. fillColorViewTopConstraint.constant = fillColorView.isHidden ? -fillColorView.bounds.size.height : 20
  687. fontViewColorPVConstraint.constant = fontViewCorloPV.isHidden ? -fontViewCorloPV.bounds.size.height : 10
  688. }
  689. func setActiveAnnotationType(_ activeAnnotationType: KMActiveAnnotationType) {
  690. self.activeAnnotationType = activeAnnotationType
  691. switch activeAnnotationType {
  692. case .highlight, .strikeOut, .underline:
  693. fontView.isHidden = true
  694. borderAndLineView.isHidden = true
  695. fillColorView.isHidden = true
  696. rotateView.isHidden = true
  697. typeView.isHidden = true
  698. dateView.isHidden = true
  699. iconView.isHidden = true
  700. createMarkupProperties()
  701. case .inkAndLine:
  702. fontView.isHidden = true
  703. fillColorView.isHidden = true
  704. rotateView.isHidden = true
  705. typeView.isHidden = true
  706. dateView.isHidden = true
  707. iconView.isHidden = true
  708. createInkAndLineProperties()
  709. case .text:
  710. fontView.isHidden = true
  711. borderAndLineView.isHidden = true
  712. fillColorView.isHidden = true
  713. rotateView.isHidden = true
  714. typeView.isHidden = true
  715. dateView.isHidden = true
  716. createTextProperties()
  717. case .squareAndCircle:
  718. fontView.isHidden = true
  719. rotateView.isHidden = true
  720. typeView.isHidden = true
  721. dateView.isHidden = true
  722. iconView.isHidden = true
  723. fillColorView.isHidden = true
  724. createSquareAndCircleProperties()
  725. case .freeText:
  726. colorView.isHidden = true
  727. rotateView.isHidden = true
  728. typeView.isHidden = true
  729. dateView.isHidden = true
  730. iconView.isHidden = true
  731. createFreeTextProperties()
  732. case .selfSignFreeText:
  733. rotateView.isHidden = true
  734. borderAndLineView.isHidden = true
  735. fillColorView.isHidden = true
  736. typeView.isHidden = true
  737. iconView.isHidden = true
  738. createSelfSignFreeTextProperties()
  739. default:
  740. break
  741. }
  742. }
  743. func createMarkupProperties() {
  744. let colorViewHeight = colorTitleLabel.frame.height + KMColorPickerViewHeight + 30
  745. colorView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: colorViewHeight)
  746. textColorBoxConstraint.constant = 10
  747. borderColorBoxConstraint.constant = 0
  748. textColorBox.isHidden = true
  749. lineWidthBox.isHidden = true
  750. imageBoxLayoutConstraint.constant = generalImageBoxView.frame.height
  751. hiddenSubviews()
  752. textColorPickerView.noContentString = true
  753. if activeAnnotationType == .highlight {
  754. textColorPickerView.annotationTypeString = NSLocalizedString("Highlight", comment: "Description for export")
  755. } else if activeAnnotationType == .strikeOut {
  756. textColorPickerView.annotationTypeString = NSLocalizedString("Strikethrough", comment: "Description for export")
  757. } else if activeAnnotationType == .underline {
  758. textColorPickerView.annotationTypeString = NSLocalizedString("Underline", comment: "Description for export")
  759. }
  760. textColorPickerView.annotationType = (activeAnnotationType == .highlight) ? .markupHighlightColors : .markupOtherColors
  761. }
  762. func openFreeTextStylesViewController() {
  763. if annotations.count == 0 {
  764. return
  765. }
  766. let vc = KMFreeTextStylesViewController()
  767. vc.annotations = annotations
  768. vc.view.frame = CGRect(x: 0, y: 0, width: 280, height: CGRectGetHeight(self.view.window?.frame ?? CGRect.zero) - 300)
  769. let createFilePopover = NSPopover()
  770. createFilePopover.contentViewController = vc
  771. createFilePopover.animates = true
  772. createFilePopover.behavior = .transient
  773. createFilePopover.show(relativeTo: CGRect(x: textImageBox.bounds.origin.x, y: 10, width: textImageBox.bounds.size.width, height: textImageBox.bounds.size.height), of: textImageBox, preferredEdge: .minY)
  774. // Assuming _textImageBox is an NSView instance
  775. createFilePopover.show(relativeTo: textImageBox.bounds, of: textImageBox, preferredEdge: .minY)
  776. // Release is not needed in Swift due to automatic reference counting (ARC)
  777. }
  778. func changeStoredFontInfo(_ sender: Any) {
  779. // if let senderFont = sender as? NSFont {
  780. // for tAnnotation in self.annotations {
  781. // tAnnotation.removeAllAppearanceStreams()
  782. // let font = senderFont.convert(tAnnotation.font)
  783. // if let validFont = font {
  784. // tAnnotation.font = validFont
  785. // }
  786. // }
  787. // }
  788. }
  789. private func updateAnnotation() {
  790. if annotationModel?.annotation != nil {
  791. if annotation is CPDFFreeTextAnnotation {
  792. let textNote = (annotation as! CPDFFreeTextAnnotation)
  793. if let isEdit = pdfView?.isEdit(withCurrentFreeText: textNote), isEdit {
  794. // pdfView?.commitEditAnnotationFreeText(textNote)
  795. pdfView?.editAnnotationFreeText(textNote)
  796. }
  797. pdfView?.setNeedsDisplay(pdfView?.activeAnnotation)
  798. }
  799. for tAnnotation in annotations {
  800. if tAnnotation is CPDFStampAnnotation {
  801. (tAnnotation as? KMSelfSignAnnotation)?.updateAppearanceStream()
  802. }
  803. if tAnnotation is CPDFMarkupAnnotation {
  804. pdfView?.setNeedsDisplayFor(tAnnotation.page)
  805. } else {
  806. pdfView?.setNeedsDisplayAnnotationViewFor(tAnnotation.page)
  807. }
  808. }
  809. }
  810. if annotationType == .freeText {
  811. textAnnotationImageView.image = annotationModel?.annotationImage
  812. } else {
  813. generalImageView.image = annotationModel?.annotationImage
  814. }
  815. }
  816. override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
  817. if self.annotation.isEqual(to: object) == false {
  818. return
  819. }
  820. let newValue = change?[NSKeyValueChangeKey.newKey] as? NSObject
  821. let oldValue = change?[NSKeyValueChangeKey.oldKey]
  822. if let data = newValue?.isEqual(to: oldValue), data {
  823. return
  824. }
  825. if keyPath == "string" {
  826. if newValue == nil || newValue is NSNull {
  827. return
  828. }
  829. //处理编辑时光标后移
  830. if self.isTextEdit == false {
  831. self.noteTextView.string = newValue as? String ?? ""
  832. }
  833. self.isTextEdit = false
  834. } else {
  835. self.reloadData()
  836. if self.isannotationMode {
  837. self.updateannotationMode()
  838. }
  839. }
  840. }
  841. // MARK: Line Note
  842. func createInkAndLineProperties() {
  843. if annotationType == .ink {
  844. let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight + 30
  845. colorView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: colorViewHeight)
  846. textColorBoxConstraint.constant = 10
  847. borderColorBoxConstraint.constant = 0
  848. textColorBox.isHidden = true
  849. lineWidthBox.isHidden = true
  850. imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
  851. hiddenSubviews()
  852. textColorPickerView.noContentString = true
  853. textColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
  854. textColorPickerView.annotationType = .inkColors
  855. } else if annotationType == .line || annotationType == .arrow {
  856. let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight * 2 + 40
  857. colorView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: colorViewHeight)
  858. textColorBoxConstraint.constant = KMColorPickerViewHeight + 20
  859. borderColorBoxConstraint.constant = 0
  860. lineWidthBox.isHidden = true
  861. textColorPickerViewConstant.constant = 57
  862. imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
  863. hiddenSubviews()
  864. borderColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
  865. textColorPickerView.annotationTypeString = NSLocalizedString("Fill Color", comment: "")
  866. borderColorPickerView.annotationType = .lineColors
  867. textColorPickerView.annotationType = .lineFillColors
  868. borderColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
  869. borderColorPickerView.annotationType = .lineColors
  870. }
  871. lineTypeLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
  872. lineTypeLabel.textColor = KMAppearance.Layout.h0Color()
  873. lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
  874. lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  875. lineStyleButton.wantsLayer = true
  876. dottedLineStyleButton.wantsLayer = true
  877. rightArrowStyleButton.wantsLayer = true
  878. lineStyleButton.image = borderStyleSolid(false)
  879. dottedLineStyleButton.image = borderStyleDashed(false)
  880. rightArrowStyleButton.image = lineStyleRightArrow(false)
  881. if annotationModel?.style() == .solid {
  882. lineStyleCount = 0
  883. lineStyleButton.image = borderStyleSolid(true)
  884. lineStyleBox.borderWidth = 0
  885. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  886. } else if annotationModel?.style() == .dashed {
  887. lineStyleCount = 1
  888. dottedLineStyleButton.image = borderStyleDashed(true)
  889. dottedLineStyleBox.borderWidth = 0
  890. dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
  891. }
  892. if (annotationType == .line || annotationType == .arrow) && annotationModel?.endLineStyle() == .closedArrow {
  893. lineStyleCount = 2
  894. rightArrowStyleButton.image = lineStyleRightArrow(true)
  895. rightArrowStyleBox.borderWidth = 0
  896. rightArrowStyleBox.fillColor = KMAppearance.Status.selColor()
  897. }
  898. }
  899. func createTextProperties() {
  900. makeNoteIcons()
  901. let colorViewHeight = colorTitleLabel.frame.height + KMColorPickerViewHeight + 30
  902. colorView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: colorViewHeight)
  903. textColorBoxConstraint.constant = 10
  904. borderColorBoxConstraint.constant = 0
  905. textColorBox.isHidden = true
  906. lineWidthBox.isHidden = true
  907. imageBoxLayoutConstraint.constant = generalImageBoxView.frame.height
  908. hiddenSubviews()
  909. textColorPickerView.annotationTypeString = NSLocalizedString("Anchored Note", comment: "Description for export")
  910. commentButton.title = NSLocalizedString("Comment", comment: "")
  911. commentButton.toolTip = NSLocalizedString("Comment", comment: "")
  912. commentButton.setTitleColor(KMAppearance.Layout.h0Color())
  913. paragraphButton.title = NSLocalizedString("Paragraph", comment: "")
  914. paragraphButton.toolTip = NSLocalizedString("Paragraph", comment: "")
  915. paragraphButton.setTitleColor(KMAppearance.Layout.h0Color())
  916. insertButton.title = NSLocalizedString("Insert", comment: "")
  917. insertButton.toolTip = NSLocalizedString("Insert", comment: "")
  918. insertButton.setTitleColor(KMAppearance.Layout.h0Color())
  919. addParagraphButton.title = NSLocalizedString("New Paragraph", comment: "")
  920. addParagraphButton.toolTip = NSLocalizedString("New Paragraph", comment: "")
  921. addParagraphButton.setTitleColor(KMAppearance.Layout.h0Color())
  922. keyButton.title = NSLocalizedString("Key", comment: "")
  923. keyButton.toolTip = NSLocalizedString("Key", comment: "")
  924. keyButton.setTitleColor(KMAppearance.Layout.h0Color())
  925. noteButton.title = NSLocalizedString("Note", comment: "")
  926. noteButton.toolTip = NSLocalizedString("Note", comment: "")
  927. noteButton.setTitleColor(KMAppearance.Layout.h0Color())
  928. helpButton.title = NSLocalizedString("Help", comment: "")
  929. helpButton.toolTip = NSLocalizedString("Help", comment: "")
  930. helpButton.setTitleColor(KMAppearance.Layout.h0Color())
  931. // let languages = NSLocale.preferredLanguages
  932. var currentLocaleLanguageCode = NSLocalizedString("en-new", comment: "")
  933. // if let firstLanguage = languages.first {
  934. // currentLocaleLanguageCode = firstLanguage
  935. // if currentLocaleLanguageCode.hasPrefix("zh") {
  936. // currentLocaleLanguageCode = "zh"
  937. // }
  938. // }
  939. let buttonArray: [NSButton] = [commentButton, keyButton, noteButton, helpButton, addParagraphButton, paragraphButton, insertButton]
  940. for button in buttonArray {
  941. button.wantsLayer = true
  942. button.layer?.cornerRadius = 6.0
  943. if currentLocaleLanguageCode == "zh" {
  944. iconButtonHeightConstant.constant = 56.0
  945. button.imagePosition = .imageAbove
  946. } else {
  947. iconButtonHeightConstant.constant = 50.0
  948. button.imagePosition = .imageOnly
  949. }
  950. }
  951. iconButtonArray = [commentBox, keyBox, noteBox, helpBox, addParagraphBox, paragraphBox, insertBox]
  952. let iconType = UInt((annotationModel?.anchoredIconType().rawValue)!)
  953. clickAnnotationTextIconButtonAction(iconType: iconType, boxArr: iconButtonArray)
  954. textColorPickerView.annotationType = .anchoredNoteColors
  955. textColorPickerView.isCallColorPanelAction = true
  956. }
  957. func clickAnnotationTextIconButtonAction(iconType: UInt, boxArr buttonArr: [NSBox]) {
  958. for i in 0..<buttonArr.count {
  959. if iconType == 0 {
  960. commentButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  961. commentButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteAnnotationSel)
  962. } else {
  963. commentButton.layer?.backgroundColor = NSColor.clear.cgColor
  964. commentButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteAnnotationNor)
  965. }
  966. if iconType == 1 {
  967. keyButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  968. keyButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteKeywordSel)
  969. } else {
  970. keyButton.layer?.backgroundColor = NSColor.clear.cgColor
  971. keyButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteKeywordNor)
  972. }
  973. if iconType == 2 {
  974. noteButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  975. noteButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNotesSel)
  976. } else {
  977. noteButton.layer?.backgroundColor = NSColor.clear.cgColor
  978. noteButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNotesNor)
  979. }
  980. if iconType == 3 {
  981. helpButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  982. helpButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteHelpSel)
  983. } else {
  984. helpButton.layer?.backgroundColor = NSColor.clear.cgColor
  985. helpButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteHelpNor)
  986. }
  987. if iconType == 4 {
  988. addParagraphButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  989. addParagraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNewparagraphSel)
  990. } else {
  991. addParagraphButton.layer?.backgroundColor = NSColor.clear.cgColor
  992. addParagraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNewparagraphNor)
  993. }
  994. if iconType == 5 {
  995. paragraphButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  996. paragraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteParagraphSel)
  997. } else {
  998. paragraphButton.layer?.backgroundColor = NSColor.clear.cgColor
  999. paragraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteParagraphNor)
  1000. }
  1001. if iconType == 6 {
  1002. insertButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  1003. insertButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteInsertSel)
  1004. } else {
  1005. insertButton.layer?.backgroundColor = NSColor.clear.cgColor
  1006. insertButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteInsertNor)
  1007. }
  1008. }
  1009. }
  1010. func borderStyleSolid(_ isSelect: Bool) -> NSImage {
  1011. let size = NSSize(width: 49.0, height: 12.0)
  1012. let image = NSImage(size: size, flipped: false, drawingHandler: { rect in
  1013. let path = NSBezierPath(rect: NSRect(x: 15.0, y: 5.0, width: 20.0, height: 1.0))
  1014. path.lineWidth = 2.0
  1015. isSelect ? KMAppearance.Layout.m_1Color().setStroke() : KMAppearance.Layout.m_1Color().setStroke()
  1016. path.stroke()
  1017. return true
  1018. })
  1019. return image
  1020. }
  1021. func borderStyleDashed(_ isSelect: Bool) -> NSImage {
  1022. let size = NSSize(width: 49.0, height: 12.0)
  1023. let image = NSImage(size: size, flipped: false, drawingHandler: { rect in
  1024. let path = NSBezierPath()
  1025. path.move(to: NSPoint(x: 15.0, y: 5.0))
  1026. path.line(to: NSPoint(x: 19.0, y: 5.0))
  1027. path.move(to: NSPoint(x: 23.0, y: 5.0))
  1028. path.line(to: NSPoint(x: 27.0, y: 5.0))
  1029. path.move(to: NSPoint(x: 31.0, y: 5.0))
  1030. path.line(to: NSPoint(x: 35.0, y: 5.0))
  1031. path.lineWidth = 2.0
  1032. isSelect ? KMAppearance.Layout.m_1Color().setStroke() : KMAppearance.Layout.m_1Color().setStroke()
  1033. path.stroke()
  1034. return true
  1035. })
  1036. return image
  1037. }
  1038. func lineStyleRightArrow(_ isSelect: Bool) -> NSImage {
  1039. let size = NSSize(width: 49.0, height: 12.0)
  1040. let image = NSImage(size: size, flipped: false, drawingHandler: { rect in
  1041. let path = NSBezierPath()
  1042. path.move(to: NSPoint(x: 6.0, y: 6.0))
  1043. path.line(to: NSPoint(x: 43.0, y: 6.0))
  1044. path.move(to: NSPoint(x: 32.0, y: 3.0))
  1045. path.line(to: NSPoint(x: 43.0, y: 6.0))
  1046. path.line(to: NSPoint(x: 32.0, y: 9.0))
  1047. path.close()
  1048. path.lineWidth = 2.0
  1049. if isSelect {
  1050. KMAppearance.Layout.l0Color().setStroke()
  1051. } else {
  1052. KMAppearance.Interactive.s0Color().setStroke()
  1053. }
  1054. path.stroke()
  1055. return true
  1056. })
  1057. return image
  1058. }
  1059. // MARK: SKSquareNote、SKCircleNote、SKArrowNote Properties
  1060. func createSquareAndCircleProperties() {
  1061. let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight * 2 + 40
  1062. colorView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: colorViewHeight)
  1063. textColorBoxConstraint.constant = KMColorPickerViewHeight + 20
  1064. borderColorBoxConstraint.constant = 0
  1065. lineWidthBox.isHidden = true
  1066. textColorPickerViewConstant.constant = 57
  1067. imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
  1068. hiddenSubviews()
  1069. lineTypeLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
  1070. lineTypeLabel.textColor = KMAppearance.Layout.h0Color()
  1071. lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
  1072. lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  1073. textColorPickerView.annotationTypeString = NSLocalizedString("Fill Color", comment: "")
  1074. borderColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
  1075. textColorPickerView.annotationType = .lineFillColors
  1076. borderColorPickerView.annotationType = .lineColors
  1077. lineStyleButton.wantsLayer = true
  1078. dottedLineStyleButton.wantsLayer = true
  1079. rightArrowStyleButton.wantsLayer = true
  1080. lineStyleButton.image = borderStyleSolid(false)
  1081. dottedLineStyleButton.image = borderStyleDashed(false)
  1082. if annotationModel?.annotation != nil {
  1083. if annotationModel?.annotation.borderStyle() == .solid {
  1084. lineStyleCount = 0
  1085. lineStyleButton.image = borderStyleSolid(true)
  1086. lineStyleBox.borderWidth = 0
  1087. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  1088. } else if annotationModel?.annotation.borderStyle() == .dashed {
  1089. lineStyleCount = 1
  1090. dottedLineStyleButton.image = borderStyleDashed(true)
  1091. dottedLineStyleBox.borderWidth = 1
  1092. dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
  1093. }
  1094. } else {
  1095. if annotationModel?.style() == .solid {
  1096. lineStyleCount = 0
  1097. lineStyleButton.image = borderStyleSolid(true)
  1098. lineStyleBox.borderWidth = 0
  1099. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  1100. } else if annotationModel?.style() == .dashed {
  1101. lineStyleCount = 1
  1102. dottedLineStyleButton.image = borderStyleDashed(true)
  1103. dottedLineStyleBox.borderWidth = 1
  1104. dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
  1105. }
  1106. }
  1107. }
  1108. // MARK: SKFreeTextNote、PDFAnnotationFreeText Properties
  1109. func createFreeTextProperties() {
  1110. imageBox.fillColor = KMAppearance.Layout.w0Color()
  1111. textColorBox.isHidden = true
  1112. lineWidthBox.isHidden = true
  1113. imageBoxLayoutConstraint.constant = CGRectGetHeight(textImageBoxView.frame)
  1114. textImageBox.downCallback = { [weak self] downEntered, mouseBox, event in
  1115. if downEntered {
  1116. self?.openFreeTextStylesViewController()
  1117. }
  1118. }
  1119. textImageUpDateButton.wantsLayer = true
  1120. textImageBoxButton.image = NSImage(named: KMImageNameUXIconBtnTriDownNor)
  1121. textImageBoxButton.isEnabled = true
  1122. textImageUpDateButton.title = NSLocalizedString("Click to refresh", comment: "")
  1123. textImageUpDateButton.setTitleColor(KMAppearance.Layout.w0Color())
  1124. textImageUpDateButton.layer?.cornerRadius = 1.0
  1125. textImageUpDateButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  1126. textImageUpDateButton.isHidden = true
  1127. hiddenSubviews()
  1128. fontViewCorloPV.noContentString = true
  1129. fontViewCorloPV.annotationTypeString = NSLocalizedString("Color", comment: "")
  1130. fillColorPickerView.noContentString = true
  1131. fillColorPickerView.annotationTypeString = NSLocalizedString("Color", comment: "")
  1132. lineTypeLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
  1133. lineTypeLabel.textColor = KMAppearance.Layout.h0Color()
  1134. leftAlignButton.toolTip = NSLocalizedString("Left Alignment", comment: "")
  1135. centerAlignButton.toolTip = NSLocalizedString("Center", comment: "")
  1136. rightAlignButton.toolTip = NSLocalizedString("Right Alignment", comment: "")
  1137. lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
  1138. lineWidthComboBox.stringValue = String(format: "%0.1f pt", Float((annotationModel?.lineWidth())!))
  1139. leftRotateBox.borderColor = KMAppearance.Interactive.s0Color()
  1140. leftRotateBox.borderWidth = 0.5
  1141. leftRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwiseNor)
  1142. leftRotateBox.downCallback = { [weak self] downEntered, mouseBox, event in
  1143. if downEntered {
  1144. self?.leftRotateBox.fillColor = KMAppearance.Status.selColor()
  1145. self?.leftRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwisePre)
  1146. } else {
  1147. self?.leftRotateBox.fillColor = KMAppearance.Layout.w0Color()
  1148. self?.leftRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwiseNor)
  1149. }
  1150. }
  1151. rightRotateBox.borderColor = KMAppearance.Interactive.s0Color()
  1152. rightRotateBox.borderWidth = 0.5
  1153. rightRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwiseNor)
  1154. rightRotateBox.downCallback = { [weak self] downEntered, mouseBox, event in
  1155. if downEntered {
  1156. self?.rightRotateBox.fillColor = KMAppearance.Status.selColor()
  1157. self?.rightRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwisePre)
  1158. } else {
  1159. self?.rightRotateBox.fillColor = KMAppearance.Layout.w0Color()
  1160. self?.rightRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwiseNor)
  1161. }
  1162. }
  1163. lineStyleButton.wantsLayer = true
  1164. dottedLineStyleButton.wantsLayer = true
  1165. rightArrowStyleButton.wantsLayer = true
  1166. lineStyleButton.image = borderStyleSolid(false)
  1167. dottedLineStyleButton.image = borderStyleDashed(false)
  1168. if annotationModel?.style() == .solid {
  1169. lineStyleCount = 0
  1170. lineStyleButton.image = borderStyleSolid(true)
  1171. lineStyleBox.borderWidth = 0
  1172. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  1173. lineStyleBox.borderWidth = 0
  1174. } else if annotationModel?.style() == .dashed {
  1175. lineStyleCount = 1
  1176. dottedLineStyleButton.image = borderStyleDashed(true)
  1177. dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
  1178. dottedLineStyleBox.borderWidth = 0
  1179. } else {
  1180. lineStyleCount = 0
  1181. lineStyleButton.image = borderStyleSolid(true)
  1182. lineStyleBox.borderWidth = 0
  1183. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  1184. lineStyleBox.borderWidth = 0
  1185. }
  1186. fontViewCorloPV.annotationType = .freeTextColors
  1187. fillColorPickerView.annotationType = .freeTextFillColors
  1188. }
  1189. func alignmentTypeSelected(_ type: KMFreeTextAnnotationAlignmentType) {
  1190. annotationAlignment = type
  1191. selectedAlignmentButtonLayer?.removeFromSuperlayer()
  1192. selectedAlignmentButtonLayer = CALayer()
  1193. selectedAlignmentButtonLayer?.cornerRadius = 6.0
  1194. leftAlignButton.wantsLayer = true
  1195. centerAlignButton.wantsLayer = true
  1196. rightAlignButton.wantsLayer = true
  1197. selectedAlignmentButtonLayer?.bounds = leftAlignButton.layer?.bounds ?? CGRect.zero
  1198. selectedAlignmentButtonLayer?.anchorPoint = CGPoint(x: 0, y: 0)
  1199. var color = NSColor(red: 71/255.0, green: 126/255.0, blue: 222/255.0, alpha: 0.16)
  1200. if #available(macOS 10.14, *) {
  1201. let appearanceName = NSApp.effectiveAppearance.bestMatch(from: [.aqua, .darkAqua])
  1202. if appearanceName == .darkAqua {
  1203. color = NSColor(red: 34/255.0, green: 122/255.0, blue: 255/255.0, alpha: 0.3)
  1204. }
  1205. }
  1206. selectedAlignmentButtonLayer?.backgroundColor = color.cgColor
  1207. leftAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignLeftNor)
  1208. centerAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignCenterNor)
  1209. rightAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignRightNor)
  1210. if type == .left {
  1211. leftAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignLeftSel)
  1212. } else if type == .center {
  1213. centerAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignCenterSel)
  1214. } else if type == .right {
  1215. rightAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignRightSel)
  1216. }
  1217. DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { [weak self] in
  1218. guard let self = self else { return }
  1219. if type == .left {
  1220. self.leftAlignButton.layer?.insertSublayer(self.selectedAlignmentButtonLayer!, at: 0)
  1221. } else if type == .center {
  1222. self.centerAlignButton.layer?.insertSublayer(self.selectedAlignmentButtonLayer!, at: 0)
  1223. } else if type == .right {
  1224. self.rightAlignButton.layer?.insertSublayer(self.selectedAlignmentButtonLayer!, at: 0)
  1225. }
  1226. }
  1227. }
  1228. // MARK: SKFreeTextNote、KMSelfSignAnnotationFreeText Properties
  1229. func createSelfSignFreeTextProperties() {
  1230. let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight + 30
  1231. colorView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: colorViewHeight)
  1232. textColorBoxConstraint.constant = 10
  1233. borderColorBoxConstraint.constant = 0
  1234. textColorBox.isHidden = true
  1235. lineWidthBox.isHidden = true
  1236. imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
  1237. hiddenSubviews()
  1238. fontViewTopConstant.constant = colorView.frame.size.height + opacityView.frame.size.height - 10 + 10
  1239. ColorViewTopConstant.constant = -(fontView.frame.size.height + fontViewTopConstant.constant)
  1240. dateViewTopConstant.constant = fontView.frame.size.height + 30
  1241. fontViewCorloPV.noContentString = true
  1242. fontViewCorloPV.annotationTypeString = ""
  1243. textColorPickerView.annotationTypeString = NSLocalizedString("Background", comment: "")
  1244. dateCheckButton.title = NSLocalizedString("Time", comment: "")
  1245. if let attrTitle = dateCheckButton.attributedTitle.mutableCopy() as? NSMutableAttributedString {
  1246. let len = attrTitle.length
  1247. let range = NSRange(location: 0, length: len)
  1248. attrTitle.addAttribute(.foregroundColor, value: KMAppearance.Layout.h1Color(), range: range)
  1249. attrTitle.fixAttributes(in: range)
  1250. dateCheckButton.attributedTitle = attrTitle
  1251. }
  1252. if activeAnnotationType == .selfSignFreeText { // 添加日期 字体默认颜色不要透明色
  1253. textColorPickerView.annotationType = .freeTextFillColors
  1254. fontViewCorloPV.annotationType = .freeTextColors
  1255. } else {
  1256. textColorPickerView.annotationType = .freeTextColors
  1257. fontViewCorloPV.annotationType = .freeTextFillColors
  1258. }
  1259. }
  1260. func setFontStyle(fontName: String, currentStyle style: String?) -> UInt {
  1261. var selectIndex: UInt = 0
  1262. let menu = NSMenu()
  1263. if let fontFamily = NSFontManager.shared.availableMembers(ofFontFamily: fontName) {
  1264. for i in 0..<fontFamily.count {
  1265. let array = fontFamily[i]
  1266. if let styleName = array[1] as? String {
  1267. if style == styleName {
  1268. selectIndex = UInt(i)
  1269. }
  1270. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: fontName, NSFontDescriptor.AttributeName.face: styleName])
  1271. let font = NSFont(descriptor: attributeFontDescriptor, size: 12.0)
  1272. let attrited = [NSAttributedString.Key.font: font]
  1273. let string = NSAttributedString(string: styleName, attributes: attrited)
  1274. let item = NSMenuItem()
  1275. item.attributedTitle = string
  1276. menu.addItem(item)
  1277. }
  1278. }
  1279. }
  1280. if style == nil {
  1281. selectIndex = 0
  1282. }
  1283. fontStylePopUpButton.menu = menu
  1284. return selectIndex
  1285. }
  1286. // MARK: UI Action
  1287. @IBAction func colorPickerViewAction(_ sender: Any) {
  1288. var fillColor: NSColor = NSColor.clear
  1289. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  1290. if let textColor = textColorPickerView.color {
  1291. textColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  1292. if fabs(opacity - 0) < 0.001 {
  1293. if annotationType == .square || annotationType == .circle || annotationType == .line || annotationType == .arrow {
  1294. annotationModel?.setInteriorOpacity(0)
  1295. annotationModel?.setInteriorColor(.black)
  1296. } else if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1297. annotationModel?.setOpacity(0)
  1298. annotationModel?.setFontColor(.black)
  1299. } else {
  1300. annotationModel?.setOpacity(0)
  1301. annotationModel?.setFontColor(.black)
  1302. }
  1303. } else {
  1304. if annotationType == .square || annotationType == .circle || annotationType == .line || annotationType == .arrow {
  1305. annotationModel?.setInteriorOpacity(opacity)
  1306. annotationModel?.setInteriorColor(textColor)
  1307. } else if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1308. annotationModel?.setOpacity(opacity)
  1309. annotationModel?.setFontColor(textColor)
  1310. } else {
  1311. annotationModel?.setOpacity(opacity)
  1312. annotationModel?.setColor(textColor)
  1313. }
  1314. }
  1315. opacitySlider.floatValue = Float(opacity)
  1316. let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
  1317. fillColor = color
  1318. if annotationModel?.annotations != nil {
  1319. if annotationModel?.annotation is CPDFFreeTextAnnotation {
  1320. let textNote = (annotationModel?.annotation as! CPDFFreeTextAnnotation)
  1321. if let isEdit = pdfView?.isEdit(withCurrentFreeText: textNote), isEdit {
  1322. pdfView?.setEditAnnotationFreeTextColor(textColor, freeText: textNote)
  1323. } else {
  1324. updateAnnotation()
  1325. }
  1326. } else {
  1327. updateAnnotation()
  1328. }
  1329. generalImageView.image = annotationModel?.annotationImage
  1330. } else {
  1331. updateAnnotation()
  1332. }
  1333. }
  1334. }
  1335. @IBAction func fillColorPickerViewAction(_ sender: Any) {
  1336. var fillColor = NSColor.clear
  1337. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  1338. if let borderColor = borderColorPickerView.color {
  1339. borderColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  1340. opacitySlider.floatValue = Float(opacity)
  1341. let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
  1342. fillColor = color
  1343. }
  1344. if annotationType == .freeText {
  1345. if let fillColorPickerColor = fillColorPickerView.color {
  1346. fillColorPickerColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  1347. opacitySlider.floatValue = Float(opacity)
  1348. let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
  1349. annotationModel?.setColor(color)
  1350. annotationModel?.setOpacity(opacity)
  1351. }
  1352. } else {
  1353. annotationModel?.setColor(fillColor)
  1354. annotationModel?.setOpacity(opacity)
  1355. }
  1356. updateAnnotation()
  1357. }
  1358. @IBAction func fontViewCorloPVAction(_ sender: Any) {
  1359. // var fillColor: NSColor = NSColor.clear
  1360. // var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  1361. //
  1362. // if let textColor = fontViewCorloPV.color {
  1363. // textColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  1364. // if fabs(opacity - 0) < 0.001 {
  1365. // if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1366. // annotationModel?.setOpacity(0)
  1367. // annotationModel?.setFontColor(.black)
  1368. // } else {
  1369. // annotationModel?.setOpacity(0)
  1370. // annotationModel?.setFontColor(.black)
  1371. // }
  1372. // } else {
  1373. // if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1374. // annotationModel?.setOpacity(opacity)
  1375. // annotationModel?.setFontColor(textColor)
  1376. // } else {
  1377. // annotationModel?.setOpacity(opacity)
  1378. // annotationModel?.setColor(textColor)
  1379. // }
  1380. // }
  1381. //
  1382. // opacitySlider.floatValue = Float(opacity)
  1383. //
  1384. // if annotationModel?.annotation != nil {
  1385. // if annotationModel?.annotation is CPDFFreeTextAnnotation {
  1386. // let textNote = (annotationModel?.annotation as! CPDFFreeTextAnnotation)
  1387. // if let isEdit = pdfView?.isEdit(withCurrentFreeText: textNote), isEdit {
  1388. // pdfView?.setEditAnnotationFreeTextColor(textColor, freeText: textNote)
  1389. // } else {
  1390. // updateAnnotation()
  1391. // }
  1392. // } else {
  1393. // updateAnnotation()
  1394. // }
  1395. // generalImageView.image = annotationModel?.annotationImage
  1396. // } else {
  1397. // updateAnnotation()
  1398. // }
  1399. // }
  1400. if annotationType == .freeText {
  1401. annotationModel?.setFontColor(fontViewCorloPV.color)
  1402. } else {
  1403. annotationModel?.setColor(fontViewCorloPV.color)
  1404. }
  1405. updateAnnotation()
  1406. }
  1407. @IBAction func opacitySliderAction(_ sender: Any) {
  1408. var opcity = CGFloat(opacitySlider.floatValue)
  1409. if opcity == 0 {
  1410. opcity = 0.0001
  1411. }
  1412. if annotationType == .signFalse ||
  1413. annotationType == .signTure ||
  1414. annotationType == .signDot ||
  1415. annotationType == .signCircle ||
  1416. annotationType == .signLine {
  1417. annotationModel?.setOpacity(opcity)
  1418. } else if annotationType == .square ||
  1419. annotationType == .circle {
  1420. if opcity != 0 {
  1421. annotationModel?.setOpacity(opcity)
  1422. annotationModel?.setInteriorOpacity(opcity)
  1423. } else {
  1424. annotationModel?.setColor(nil)
  1425. annotationModel?.setInteriorColor(nil)
  1426. }
  1427. } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
  1428. annotationModel?.setOpacity(opcity)
  1429. var color = annotationModel?.fontColor()
  1430. if annotationModel?.opacity() != 0 {
  1431. var red: CGFloat = 0.0
  1432. var green: CGFloat = 0.0
  1433. var blue: CGFloat = 0.0
  1434. var opacity: CGFloat = 0.0
  1435. color?.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  1436. color = NSColor(red: red, green: green, blue: blue, alpha: (annotationModel?.opacity())!)
  1437. } else {
  1438. color = .clear
  1439. }
  1440. } else {
  1441. annotationModel?.setOpacity(opcity)
  1442. }
  1443. opacityComboBox.stringValue = "\(Int(opcity * 100))%"
  1444. updateAnnotation()
  1445. }
  1446. @IBAction func opacityComboBoxAction(_ sender: Any) {
  1447. opacitySlider.floatValue = Float(opacityComboBox.floatValue / 100)
  1448. var opcity = CGFloat(opacitySlider.floatValue)
  1449. if opcity == 0 {
  1450. opcity = 0.0001
  1451. }
  1452. if annotationType == .signFalse ||
  1453. annotationType == .signTure ||
  1454. annotationType == .signDot ||
  1455. annotationType == .signCircle ||
  1456. annotationType == .signLine {
  1457. annotationModel?.setOpacity(opcity)
  1458. } else if annotationType == .square ||
  1459. annotationType == .circle {
  1460. if opcity != 0 {
  1461. annotationModel?.setOpacity(opcity)
  1462. annotationModel?.setInteriorOpacity(opcity)
  1463. } else {
  1464. annotationModel?.setColor(nil)
  1465. annotationModel?.setInteriorColor(nil)
  1466. }
  1467. } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
  1468. annotationModel?.setInteriorOpacity(opcity)
  1469. } else {
  1470. annotationModel?.setOpacity(opcity)
  1471. }
  1472. opacitySlider.floatValue = Float(opcity)
  1473. opacitySlider.toolTip = "\(Int(opcity * 100))%"
  1474. updateAnnotation()
  1475. }
  1476. @IBAction func lineWidthSliderAction(_ sender: Any) {
  1477. annotationModel?.setLineWidth(CGFloat(lineWidthSlider.floatValue))
  1478. lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  1479. updateAnnotation()
  1480. }
  1481. @IBAction func lineWidthComboBoxAction(_ sender: Any) {
  1482. var lineWidth = lineWidthComboBox.floatValue
  1483. if lineWidth > 18 {
  1484. lineWidth = 18
  1485. } else if lineWidth < 0.5 {
  1486. lineWidth = 0.5
  1487. }
  1488. annotationModel?.setLineWidth(CGFloat(lineWidth))
  1489. lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
  1490. updateAnnotation()
  1491. }
  1492. @IBAction func alignButtonAction(_ sender: NSButton) {
  1493. var alignmentType: KMFreeTextAnnotationAlignmentType = .left
  1494. if annotationModel?.annotations != nil {
  1495. for tAnnotation in self.annotations {
  1496. switch sender.tag {
  1497. case 0:
  1498. if tAnnotation is CPDFFreeTextAnnotation {
  1499. (tAnnotation as! CPDFFreeTextAnnotation).alignment = .left
  1500. }
  1501. alignmentType = .left
  1502. case 1:
  1503. if tAnnotation is CPDFFreeTextAnnotation {
  1504. (tAnnotation as! CPDFFreeTextAnnotation).alignment = .center
  1505. }
  1506. alignmentType = .center
  1507. case 2:
  1508. if tAnnotation is CPDFFreeTextAnnotation {
  1509. (tAnnotation as! CPDFFreeTextAnnotation).alignment = .right
  1510. }
  1511. alignmentType = .right
  1512. default:
  1513. break
  1514. }
  1515. }
  1516. } else {
  1517. switch sender.tag {
  1518. case 0:
  1519. annotationModel?.setAlignment(.left)
  1520. alignmentType = .left
  1521. case 1:
  1522. annotationModel?.setAlignment(.center)
  1523. alignmentType = .center
  1524. case 2:
  1525. annotationModel?.setAlignment(.right)
  1526. alignmentType = .right
  1527. default:
  1528. break
  1529. }
  1530. }
  1531. alignmentTypeSelected(alignmentType)
  1532. updateAnnotation()
  1533. NotificationCenter.default.post(name: NSNotification.Name("KMAnnotationAlignmentTypeNotification"),
  1534. object: "\(alignmentType.rawValue)")
  1535. }
  1536. @IBAction func currentFontColorButtonAction(_ sender: NSButton) {
  1537. // if ([_annotation isKindOfClass:[PDFAnnotationFreeText class]]) {
  1538. // KMFontColorViewController *vc = [[[KMFontColorViewController alloc] initWithNibName:@"KMFontColorViewController" bundle:[NSBundle mainBundle]] autorelease];
  1539. // vc.annotationFontColor = _annotation.fontColor;
  1540. // __block typeof(self) blockSelf = self;
  1541. // vc.fontColorChangeCallback = ^(NSColor *fontColor) {
  1542. // for (PDFAnnotation *tAnnotation in blockSelf.annotations) {
  1543. // tAnnotation.fontColor = fontColor;
  1544. // }
  1545. // };
  1546. // NSPopover *popover = [[NSPopover alloc] init];
  1547. // popover.delegate = self;
  1548. // popover.contentViewController = vc;
  1549. // popover.animates = YES;
  1550. // popover.behavior = NSPopoverBehaviorTransient;
  1551. // [popover showRelativeToRect:CGRectMake([sender bounds].origin.x, 0, [sender bounds].size.width, [sender bounds].size.height) ofView:sender preferredEdge:CGRectMaxYEdge];
  1552. // [popover release];
  1553. // }
  1554. }
  1555. @IBAction func borderButtonAction(_ sender: NSButton) {
  1556. var lineWidth: CGFloat = 0.0
  1557. var lineStype: CPDFBorderStyle = .solid
  1558. var startingPoint: CPDFLineStyle = .none
  1559. var endPoint: CPDFLineStyle = .none
  1560. var dashPattern: [NSNumber] = []
  1561. var isLineAnnotation: Bool = false
  1562. if annotationModel?.annotations != nil {
  1563. for tAnnotation in self.annotations {
  1564. lineWidth = tAnnotation.lineWidth()
  1565. lineStype = tAnnotation.borderStyle()
  1566. dashPattern = tAnnotation.dashPattern() as! [NSNumber]
  1567. if tAnnotation is CPDFLineAnnotation {
  1568. isLineAnnotation = true
  1569. startingPoint = (tAnnotation as! CPDFLineAnnotation).startLineStyle
  1570. endPoint = (tAnnotation as! CPDFLineAnnotation).endLineStyle
  1571. } else {
  1572. isLineAnnotation = false
  1573. }
  1574. }
  1575. } else {
  1576. lineWidth = String(format: "%0.1f pt", (annotationModel?.lineWidth())!).stringToCGFloat()
  1577. lineStype = (annotationModel?.style())! as CPDFBorderStyle
  1578. dashPattern = (annotationModel?.dashPattern())! as [NSNumber]
  1579. if annotationModel?.annotationType == .line {
  1580. isLineAnnotation = true
  1581. startingPoint = (annotationModel?.startLineStyle())! as CPDFLineStyle
  1582. endPoint = (annotationModel?.endLineStyle())! as CPDFLineStyle
  1583. } else {
  1584. isLineAnnotation = false
  1585. }
  1586. }
  1587. let lineModel = KMLineModel(lineWidth: lineWidth, lineStype: lineStype, startingPoint: startingPoint, endPoint: endPoint, dashPattern: dashPattern, isLineAnnotation: isLineAnnotation)
  1588. let fontWindowController = KMAnnotationLineWindowController.initWindowController(lineModel)
  1589. guard let window = fontWindowController.window else { return }
  1590. // fontWindowController.annotationLineChangeBlock = { [weak self] lineNote in
  1591. // if lineNote.borderStyle() == .solid {
  1592. // self!.lineTypeButtonAction(self!.lineStyleButton)
  1593. // } else if lineNote.borderStyle() == .dashed {
  1594. // self!.lineTypeButtonAction(self!.dottedLineStyleButton)
  1595. // for tAnnotation in self!.annotations {
  1596. // tAnnotation.setDashPattern(lineNote.dashPattern())
  1597. // }
  1598. // }
  1599. // }
  1600. fontWindowController.callback = { model in
  1601. if self.annotationModel?.annotations != nil {
  1602. } else {
  1603. }
  1604. }
  1605. window.orderFront(sender)
  1606. }
  1607. func lineTypePopAction() {
  1608. annotationModel?.setStyle(CPDFBorderStyle(rawValue: lineStyleCount) ?? .solid)
  1609. updateAnnotation()
  1610. }
  1611. @IBAction func lineTypeButtonAction(_ sender: NSButton) {
  1612. let tag = sender.tag
  1613. switch tag {
  1614. case 0:
  1615. lineStyleCount = 0
  1616. refreshLineTypeUI()
  1617. lineStyleButton.image = borderStyleSolid(true)
  1618. dottedLineStyleButton.image = borderStyleDashed(false)
  1619. rightArrowStyleButton.image = lineStyleRightArrow(false)
  1620. lineTypePopAction()
  1621. case 1:
  1622. lineStyleCount = 1
  1623. refreshLineTypeUI()
  1624. lineStyleButton.image = borderStyleSolid(false)
  1625. dottedLineStyleButton.image = borderStyleDashed(true)
  1626. rightArrowStyleButton.image = lineStyleRightArrow(false)
  1627. lineTypePopAction()
  1628. case 2:
  1629. lineStyleCount = 2
  1630. refreshLineTypeUI()
  1631. lineStyleButton.image = borderStyleSolid(false)
  1632. dottedLineStyleButton.image = borderStyleDashed(false)
  1633. rightArrowStyleButton.image = lineStyleRightArrow(true)
  1634. for tAnnotation in annotations {
  1635. if tAnnotation is CPDFLineAnnotation {
  1636. (tAnnotation as! CPDFLineAnnotation).endLineStyle = .closedArrow
  1637. }
  1638. }
  1639. default:
  1640. break
  1641. }
  1642. }
  1643. @IBAction func iconButtonAction(_ sender: NSButton) {
  1644. var type: CPDFTextAnnotationIconType = .comment
  1645. switch sender.tag {
  1646. case 0:
  1647. type = .comment
  1648. case 1:
  1649. type = .key
  1650. case 2:
  1651. type = .note
  1652. case 3:
  1653. type = .help
  1654. case 4:
  1655. type = .newParagraph
  1656. case 5:
  1657. type = .paragraph
  1658. case 6, _:
  1659. type = .insert
  1660. }
  1661. if annotationModel?.annotations != nil {
  1662. for tAnnotation in self.annotations {
  1663. if tAnnotation is CPDFTextAnnotation {
  1664. (tAnnotation as! CPDFTextAnnotation).setIconType(type)
  1665. }
  1666. }
  1667. self.updateAnnotation()
  1668. } else {
  1669. annotationModel?.setAnchoredIconType(type)
  1670. }
  1671. generalImageView.image = annotationModel?.annotationImage
  1672. updateannotationMode()
  1673. clickAnnotationTextIconButtonAction(iconType: UInt(sender.tag), boxArr: iconButtonArray)
  1674. }
  1675. @IBAction func textImageBoxButtonAction(_ sender: Any) {
  1676. openFreeTextStylesViewController()
  1677. }
  1678. // MARK: Font、FontSize Action
  1679. @IBAction func fontButtonAction(_ sender: NSButton) {
  1680. let selectItem = self.fontPopUpButton.selectedItem
  1681. guard let selectItem = selectItem else { return }
  1682. let resultAtt = NSMutableAttributedString(attributedString: selectItem.attributedTitle!)
  1683. let familyString = resultAtt.string
  1684. let styleString = self.fontStylePopUpButton.selectedItem?.title
  1685. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [.family: familyString, .face: styleString as Any])
  1686. let fontSizeString = fontSizeComboBox.stringValue.replacingOccurrences(of: " pt", with: "")
  1687. let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSizeString.stringToCGFloat())
  1688. let fontModel = KMFontModel(fontName: familyString, fontWeight: styleString!, fontSize: fontSizeString.stringToCGFloat(), fontColor: textColorPickerView.color ?? .black, fontAlignment: annotationAlignment, annotationType: annotationModel!.annotationType)
  1689. let fontWindowController = KMAnnotationFontWindowController.initWindowController(fontModel)
  1690. let window = fontWindowController.window
  1691. fontWindowController.callback = { [weak self] model in
  1692. self!.alignmentTypeSelected(model.fontAlignment)
  1693. self!.textColorPickerView.color = model.fontColor
  1694. DispatchQueue.global(qos: .default).async {
  1695. let fonts = NSFontManager.shared.availableFontFamilies
  1696. let menu = NSMenu()
  1697. var selectedIndex = 0
  1698. for (index, fontName) in fonts.enumerated() {
  1699. if let font = NSFont(name: fontName, size: 12.0) {
  1700. let attributedString = NSAttributedString(string: fontName, attributes: [.font: font])
  1701. let item = NSMenuItem()
  1702. item.attributedTitle = attributedString
  1703. menu.addItem(item)
  1704. if model.fontName == font.fontName {
  1705. selectedIndex = index
  1706. }
  1707. }
  1708. }
  1709. DispatchQueue.main.async {
  1710. self!.fontPopUpButton.menu = menu
  1711. self!.fontPopUpButton.selectItem(at: selectedIndex)
  1712. }
  1713. }
  1714. let selectedStyleIndex = self!.setFontStyle(fontName: model.fontName, currentStyle: model.fontWeight)
  1715. self!.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  1716. self!.fontSizeComboBox.stringValue = String(format: "%.f pt", model.fontSize)
  1717. if self!.annotationModel?.annotations != nil {
  1718. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [.family: model.fontName, .face: model.fontWeight])
  1719. let annotationFont = NSFont(descriptor: attributeFontDescriptor, size: model.fontSize)
  1720. for tAnnotation in self!.annotations {
  1721. if tAnnotation is CPDFFreeTextAnnotation {
  1722. (tAnnotation as! CPDFFreeTextAnnotation).font = annotationFont
  1723. (tAnnotation as! CPDFFreeTextAnnotation).fontColor = model.fontColor
  1724. if model.fontAlignment == .left {
  1725. (tAnnotation as! CPDFFreeTextAnnotation).alignment = .left
  1726. } else if model.fontAlignment == .center {
  1727. (tAnnotation as! CPDFFreeTextAnnotation).alignment = .center
  1728. } else if model.fontAlignment == .right {
  1729. (tAnnotation as! CPDFFreeTextAnnotation).alignment = .right
  1730. }
  1731. }
  1732. }
  1733. self!.updateAnnotation()
  1734. } else {
  1735. self!.annotationModel?.setFontName(model.fontName)
  1736. self!.annotationModel?.setFontSize(model.fontSize)
  1737. self!.annotationModel?.setFontColor(model.fontColor)
  1738. if model.fontAlignment == .left {
  1739. self!.annotationModel?.setAlignment(.left)
  1740. } else if model.fontAlignment == .center {
  1741. self!.annotationModel?.setAlignment(.center)
  1742. } else if model.fontAlignment == .right {
  1743. self!.annotationModel?.setAlignment(.right)
  1744. }
  1745. }
  1746. }
  1747. window?.orderFront(sender)
  1748. }
  1749. @IBAction func fontPopUpButtonAction(_ sender: NSPopUpButton) {
  1750. guard let selectedItem = fontPopUpButton.selectedItem else { return }
  1751. let resultAtt = NSMutableAttributedString(attributedString: selectedItem.attributedTitle!)
  1752. let familyString = resultAtt.string
  1753. let selectIndex = setFontStyle(fontName: familyString, currentStyle: nil)
  1754. guard let styleString = fontStylePopUpButton.selectedItem?.title else { return }
  1755. fontStylePopUpButton.selectItem(at: Int(selectIndex))
  1756. if annotationModel?.annotations != nil {
  1757. for tAnnotation in annotations {
  1758. if tAnnotation is CPDFFreeTextAnnotation {
  1759. let newAnnotation = (tAnnotation as! CPDFFreeTextAnnotation)
  1760. if let font = newAnnotation.font {
  1761. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? Int {
  1762. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1763. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: CGFloat(fontSize)) {
  1764. newAnnotation.font = newFont
  1765. }
  1766. }
  1767. if let tFont = newAnnotation.font {
  1768. if let family = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
  1769. let style = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
  1770. DispatchQueue.main.async {
  1771. let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
  1772. self.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  1773. }
  1774. }
  1775. }
  1776. }
  1777. } else if tAnnotation is KMSelfSignAnnotationFreeText {
  1778. let newAnnotation = (tAnnotation as! KMSelfSignAnnotationFreeText)
  1779. if let font = newAnnotation.font {
  1780. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? Int {
  1781. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1782. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: CGFloat(fontSize)) {
  1783. newAnnotation.font = newFont
  1784. }
  1785. }
  1786. newAnnotation.updateBounds()
  1787. if let tFont = newAnnotation.font {
  1788. if let family = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
  1789. let style = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
  1790. DispatchQueue.main.async {
  1791. let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
  1792. self.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  1793. }
  1794. }
  1795. }
  1796. }
  1797. }
  1798. }
  1799. } else {
  1800. if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1801. let font = NSFont(name: (annotationModel?.fontName())!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
  1802. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? Int {
  1803. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1804. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: CGFloat(fontSize)) {
  1805. annotationModel?.setFontName(newFont.fontName)
  1806. annotationModel?.setFontSize(newFont.pointSize)
  1807. }
  1808. }
  1809. let tFont = NSFont(name: (annotationModel?.fontName())!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
  1810. if let family = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
  1811. let style = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
  1812. DispatchQueue.main.async {
  1813. let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
  1814. self.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  1815. }
  1816. }
  1817. }
  1818. }
  1819. updateannotationMode()
  1820. updateAnnotation()
  1821. }
  1822. @IBAction func fontSizeComboBoxAction(_ sender: NSComboBox) {
  1823. if annotationModel?.annotations != nil {
  1824. for tAnnotation in annotations {
  1825. if tAnnotation is CPDFFreeTextAnnotation {
  1826. let newAnnotation = (tAnnotation as! CPDFFreeTextAnnotation)
  1827. if let font = newAnnotation.font {
  1828. let newFont = NSFont(name: font.fontName, size: CGFloat(fontSizeComboBox.floatValue))
  1829. if let newFont = newFont {
  1830. newAnnotation.font = newFont
  1831. }
  1832. }
  1833. } else if tAnnotation is KMSelfSignAnnotationFreeText {
  1834. let newAnnotation = (tAnnotation as! KMSelfSignAnnotationFreeText)
  1835. if let font = newAnnotation.font {
  1836. let newFont = NSFont(name: font.fontName, size: CGFloat(fontSizeComboBox.floatValue))
  1837. if let newFont = newFont {
  1838. newAnnotation.font = newFont
  1839. }
  1840. }
  1841. newAnnotation.updateBounds()
  1842. }
  1843. }
  1844. } else {
  1845. if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1846. let font = NSFont(name: (annotationModel?.fontName()!)!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
  1847. let newFont = NSFont(name: font.fontName, size: CGFloat(fontSizeComboBox.floatValue))
  1848. if let newFont = newFont {
  1849. annotationModel?.setFontName(newFont.fontName)
  1850. annotationModel?.setFontSize(newFont.pointSize)
  1851. }
  1852. }
  1853. }
  1854. updateAnnotation()
  1855. NotificationCenter.default.post(name: NSNotification.Name("KMAnnotationFontTypeNotification"),
  1856. object: pdfView)
  1857. adjustFreeText()
  1858. }
  1859. //字重 NSFontWeight
  1860. @IBAction func fontStylePopUpButtonAction(_ sender: NSPopUpButton) {
  1861. if let styleString = self.fontStylePopUpButton.selectedItem?.title {
  1862. if annotationModel?.annotations != nil {
  1863. for tAnnotation in self.annotations {
  1864. if tAnnotation is CPDFFreeTextAnnotation {
  1865. let newAnnotation = (tAnnotation as! CPDFFreeTextAnnotation)
  1866. if let font = newAnnotation.font {
  1867. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? Int,
  1868. let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
  1869. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1870. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: CGFloat(fontSize)) {
  1871. newAnnotation.font = newFont
  1872. }
  1873. }
  1874. }
  1875. } else if tAnnotation is KMSelfSignAnnotationFreeText {
  1876. let newAnnotation = (tAnnotation as! KMSelfSignAnnotationFreeText)
  1877. if let font = newAnnotation.font {
  1878. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? Int,
  1879. let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
  1880. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1881. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: CGFloat(fontSize)) {
  1882. newAnnotation.font = newFont
  1883. }
  1884. newAnnotation.updateBounds()
  1885. }
  1886. }
  1887. }
  1888. }
  1889. } else {
  1890. if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1891. let font = NSFont(name: (annotationModel?.fontName())!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
  1892. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? Int,
  1893. let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
  1894. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1895. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: CGFloat(fontSize)) {
  1896. annotationModel?.setFontName(newFont.fontName)
  1897. annotationModel?.setFontSize(newFont.pointSize)
  1898. }
  1899. }
  1900. }
  1901. }
  1902. }
  1903. updateAnnotation()
  1904. }
  1905. @IBAction func buttonClicked_SwitchIncludeTime(_ sender: NSButton) {
  1906. for case let tAnnotation as KMSelfSignAnnotationFreeText in annotations {
  1907. tAnnotation.includeTime = sender.state == .on ? true : false
  1908. let index = datePopUpButton.indexOfSelectedItem
  1909. datePopUpButton.removeAllItems()
  1910. datePopUpButton.addItems(withTitles: KMSelfSignAnnotationFreeText.fetchAllDateString(includeTime: false))
  1911. datePopUpButton.selectItem(at: index)
  1912. if self.subType == .date && isannotationMode {
  1913. UserDefaults.standard.set(sender.state == .on ? true : false, forKey: SKAnnotationSelfSignDateFormatterIncludeTimeKey)
  1914. }
  1915. }
  1916. reloadData()
  1917. }
  1918. @IBAction func dateCheckButtonAction(_ sender: NSPopUpButton) {
  1919. for case let tAnnotation as KMSelfSignAnnotationFreeText in annotations {
  1920. if subType == .date && isannotationMode {
  1921. let fetchArray = KMSelfSignAnnotationFreeText.fetchAllDateString(includeTime: false)
  1922. if sender.indexOfSelectedItem >= 0 && sender.indexOfSelectedItem <= fetchArray.count - 1 {
  1923. UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: SKAnnotationSelfSignDateFormatterKey)
  1924. }
  1925. }
  1926. tAnnotation.dateFormatIndex = sender.indexOfSelectedItem
  1927. }
  1928. reloadData()
  1929. }
  1930. func annotationFontReload() {
  1931. DispatchQueue.global(qos: .default).async { [self] in
  1932. let fonts = NSFontManager.shared.availableFontFamilies
  1933. let menu = NSMenu()
  1934. var selectedIndex = 0
  1935. for (index, fontName) in fonts.enumerated() {
  1936. if let font = NSFont(name: fontName, size: 12.0) {
  1937. let attributedString = NSAttributedString(string: fontName, attributes: [NSAttributedString.Key.font: font])
  1938. let item = NSMenuItem()
  1939. item.attributedTitle = attributedString
  1940. menu.addItem(item)
  1941. if annotationType == .freeText {
  1942. if annotationModel?.fontName() == font.fontName {
  1943. selectedIndex = index
  1944. }
  1945. }
  1946. }
  1947. }
  1948. if annotationType == .freeText {
  1949. let freetextFont = NSFont(name: (annotationModel?.fontName() as? String)!, size: 16) ?? NSFont.systemFont(ofSize: 16)
  1950. if let family = freetextFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
  1951. let style = freetextFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
  1952. DispatchQueue.main.async { [self] in
  1953. fontPopUpButton.menu = menu
  1954. fontPopUpButton.selectItem(at: selectedIndex)
  1955. let selectedStyleIndex = setFontStyle(fontName: family, currentStyle: style)
  1956. fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  1957. }
  1958. }
  1959. }
  1960. }
  1961. }
  1962. func adjustFreeText() {
  1963. if annotationModel?.annotations != nil {
  1964. if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1965. for an in (annotationModel?.annotations)! {
  1966. if let freeTextAn = an as? CPDFFreeTextAnnotation {
  1967. let font = freeTextAn.font
  1968. var attributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: font as Any]
  1969. let style = NSMutableParagraphStyle()
  1970. style.alignment = freeTextAn.alignment
  1971. attributes[NSAttributedString.Key.paragraphStyle] = style
  1972. let contents = freeTextAn.contents ?? ""
  1973. let textViewSize = contents.boundingRect(with: CGSize(width: freeTextAn.bounds.size.width, height: CGFloat(MAXFLOAT)),
  1974. options: .usesLineFragmentOrigin,
  1975. attributes: attributes).size
  1976. var rect = freeTextAn.bounds
  1977. if textViewSize.height != freeTextAn.bounds.size.height {
  1978. rect.origin.y -= (textViewSize.height - rect.size.height)
  1979. rect.size.height = textViewSize.height
  1980. }
  1981. if textViewSize.width < freeTextAn.bounds.size.width {
  1982. rect.size.width = textViewSize.width
  1983. }
  1984. freeTextAn.bounds = rect
  1985. }
  1986. }
  1987. }
  1988. }
  1989. }
  1990. // MARK: NSNotification
  1991. @objc func textDidChange(_ notification: Notification) {
  1992. // self.isTextEdit = true
  1993. //
  1994. // if self.subType == KMSelfSignAnnotationFreeTextSubType.freeText && isannotationMode {
  1995. // if let obj = notification.object as? NSObject {
  1996. // for tAnnotation in annotations {
  1997. // tAnnotation.setString(noteTextView.string)
  1998. // }
  1999. //
  2000. // if obj.isEqual(to: noteTextView) {
  2001. // UserDefaults.standard.set(noteTextView.string, forKey: SKAnnotationSelfSignPlaceHolderStringKey)
  2002. // }
  2003. //
  2004. // if annotation.isKind(of: CPDFFreeTextAnnotation.self) {
  2005. // textAnnotationImageView.image = annotationModel?.annotationImage
  2006. // } else {
  2007. // generalImageView.image = annotationModel?.annotationImage
  2008. // }
  2009. // }
  2010. // } else {
  2011. // if let obj = notification.object as? NSObject, obj.isEqual(to: noteTextView) {
  2012. // for tAnnotation in self.annotations {
  2013. // tAnnotation.setString(noteTextView.string)
  2014. // }
  2015. // }
  2016. // }
  2017. }
  2018. @objc func textDidEndEditing(_ notification: Notification) {
  2019. self.isTextEdit = true
  2020. if self.subType == KMSelfSignAnnotationFreeTextSubType.freeText && isannotationMode {
  2021. if let obj = notification.object as? NSObject {
  2022. for tAnnotation in annotations {
  2023. tAnnotation.setString(noteTextView.string)
  2024. }
  2025. if obj.isEqual(to: noteTextView) {
  2026. UserDefaults.standard.set(noteTextView.string, forKey: SKAnnotationSelfSignPlaceHolderStringKey)
  2027. }
  2028. if annotation.isKind(of: CPDFFreeTextAnnotation.self) {
  2029. textAnnotationImageView.image = annotationModel?.annotationImage
  2030. } else {
  2031. generalImageView.image = annotationModel?.annotationImage
  2032. }
  2033. }
  2034. } else {
  2035. if let obj = notification.object as? NSObject, obj.isEqual(to: noteTextView) {
  2036. for tAnnotation in self.annotations {
  2037. tAnnotation.setString(noteTextView.string)
  2038. }
  2039. }
  2040. }
  2041. }
  2042. @objc func themeChanged(notification: NSNotification) {
  2043. DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [self] in
  2044. updateViewColor()
  2045. }
  2046. }
  2047. }
  2048. class KMGeneralAnnotationColorButton: NSButton {
  2049. var _circleColor: NSColor = .clear
  2050. var _buttonBorderColor: NSColor = .clear
  2051. // MARK: Get & Set
  2052. var circleColor: NSColor {
  2053. set {
  2054. _circleColor = newValue
  2055. needsDisplay = true
  2056. }
  2057. get {
  2058. return _circleColor
  2059. }
  2060. }
  2061. var buttonBorderColor: NSColor {
  2062. set {
  2063. _buttonBorderColor = newValue
  2064. needsDisplay = true
  2065. }
  2066. get {
  2067. return _buttonBorderColor
  2068. }
  2069. }
  2070. // MARK: Init
  2071. required init?(coder: NSCoder) {
  2072. super.init(coder: coder)
  2073. wantsLayer = true
  2074. layer?.cornerRadius = 12.0
  2075. layer?.masksToBounds = true
  2076. layer?.borderColor = NSColor.clear.cgColor
  2077. }
  2078. override func draw(_ dirtyRect: NSRect) {
  2079. super.draw(dirtyRect)
  2080. let path3 = NSBezierPath(ovalIn: NSMakeRect(3, 3, dirtyRect.size.width - 6, dirtyRect.size.height - 6))
  2081. }
  2082. }
  2083. class KMNoteIconButtonCell: NSButtonCell {
  2084. override func drawImage(_ image: NSImage, withFrame frame: NSRect, in controlView: NSView) {
  2085. let titleSize = self.attributedTitle.size()
  2086. let imageSize = self.image!.size
  2087. var rect = NSZeroRect
  2088. let leftGap = (controlView.bounds.size.width - image.size.width) / 2.0
  2089. rect.origin.x = leftGap
  2090. if self.imagePosition == .imageAbove {
  2091. rect.origin.y = 6
  2092. } else {
  2093. rect.origin.y = (controlView.frame.size.height - image.size.height) / 2.0
  2094. }
  2095. rect.size = imageSize
  2096. super.drawImage(self.image!, withFrame: rect, in: controlView)
  2097. }
  2098. override func drawTitle(_ title: NSAttributedString, withFrame frame: NSRect, in controlView: NSView) -> NSRect {
  2099. let titleSize = self.attributedTitle.size()
  2100. let imageSize = self.image!.size
  2101. let totalHeight = titleSize.height + imageSize.height + 1
  2102. var rect = NSZeroRect
  2103. rect.origin.x = (controlView.bounds.size.width - titleSize.width) / 2.0
  2104. rect.origin.y = (controlView.bounds.size.height - totalHeight) / 2.0 + imageSize.height + 1
  2105. rect.size = titleSize
  2106. return super.drawTitle(title, withFrame: rect, in: controlView)
  2107. }
  2108. }