KMEditImagePropertyViewController.swift 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. //
  2. // KMEditImagePropertyViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by lxy on 2022/12/28.
  6. //
  7. import Cocoa
  8. public enum KMOperationState {
  9. case none
  10. case began
  11. case changed
  12. case ended
  13. }
  14. enum KMEditImagePropertyViewControllerChangeType {
  15. case rotate
  16. case flip
  17. case add
  18. case move
  19. }
  20. protocol KMEditImagePropertyViewControllerDelegate: NSObject {
  21. func editImagePropertyViewControllerDidChanged(controller: KMEditImagePropertyViewController, type: KMEditImagePropertyViewControllerChangeType)
  22. }
  23. class KMEditImagePropertyViewController: NSViewController {
  24. @IBOutlet weak var backgroundView: NSView!
  25. @IBOutlet weak var titleLabel: NSTextField!
  26. @IBOutlet weak var editImageView: NSImageView!
  27. @IBOutlet weak var headerBox: NSBox!
  28. @IBOutlet weak var headerBoxHeight: NSLayoutConstraint!
  29. @IBOutlet weak var headerBoxMaginWidthConstraint: NSLayoutConstraint!
  30. @IBOutlet weak var opacityTitleLabel: NSTextField!
  31. @IBOutlet weak var opacitySlider: NSSlider!
  32. @IBOutlet weak var opacityBox: NSBox!
  33. @IBOutlet weak var opacityBoxBottomMaginConstraint: NSLayoutConstraint!
  34. @IBOutlet weak var opacityBoxTopConstraint: NSLayoutConstraint!
  35. @IBOutlet weak var cropBox: NSBox!
  36. @IBOutlet weak var confirmBox: NSBox!
  37. @IBOutlet weak var cancelBox: NSBox!
  38. @IBOutlet weak var replaceBox: NSBox!
  39. @IBOutlet weak var exportBox: NSBox!
  40. @IBOutlet weak var imageBox: NSBox!
  41. @IBOutlet weak var imageBoxHeight: NSLayoutConstraint!
  42. @IBOutlet weak var opacityBoxHeight: NSLayoutConstraint!
  43. @IBOutlet weak var buttonBoxHeight: NSLayoutConstraint!
  44. @IBOutlet weak var buttonBox: NSBox!
  45. @IBOutlet weak var rotateLeftBox: NSBox!
  46. @IBOutlet weak var rotateRightBox: NSBox!
  47. @IBOutlet weak var flipHorizontalBox: NSBox!
  48. @IBOutlet weak var flipVerticalBox: NSBox!
  49. @IBOutlet weak var alignmentView: KMEditPropertyAlignmentView!
  50. @IBOutlet weak var alignmentViewTopConstraint: NSLayoutConstraint!
  51. //NO Image
  52. @IBOutlet weak var noImageView: NSImageView!
  53. @IBOutlet weak var noTitleLabel: NSTextField!
  54. @IBOutlet weak var noSubtitleLabel: NSTextField!
  55. @IBOutlet weak var noBackgroundView: NSView!
  56. var rotateLeftVC: KMDesignPropertySelector?
  57. var rotateRightVC: KMDesignPropertySelector?
  58. var flipHorizontalVC: KMDesignPropertySelector?
  59. var flipVerticalVC: KMDesignPropertySelector?
  60. var opacityVC: KMDesignSelect?
  61. var cropVC: KMDesignButton?
  62. var confirmVC: KMDesignButton?
  63. var cancelVC: KMDesignButton?
  64. var replaceVC: KMDesignButton?
  65. var exportVC: KMDesignButton?
  66. var imagesAreas : [CPDFEditImageArea] = []
  67. var listView : CPDFListView!
  68. var editingAreas: [Any] {
  69. get {
  70. return self.listView.editingAreas() ?? []
  71. }
  72. }
  73. weak var delegate: KMEditImagePropertyViewControllerDelegate?
  74. func addNotification() {
  75. NotificationCenter.default.addObserver(self, selector: #selector(changeEffectiveAppearance), name: NSNotification.Name(rawValue: "kEffectiveAppearance"), object: nil)
  76. }
  77. func removeNotification() {
  78. NotificationCenter.default.removeObserver(self)
  79. DistributedNotificationCenter.default().removeObserver(self)
  80. }
  81. @objc func changeEffectiveAppearance() {
  82. print("changeEffectiveAppearance")
  83. let isDarkModel = NSView.isDarkModel()
  84. if isDarkModel {
  85. self.view.appearance = NSAppearance(named: .darkAqua)
  86. } else {
  87. self.view.appearance = NSAppearance(named: .aqua)
  88. }
  89. self.updateUI()
  90. }
  91. func updateUI() {
  92. let isDarkModel = NSView.isDarkModel()
  93. if isDarkModel {
  94. self.backgroundView.backgroundColor(NSColor.km_init(hex: "#252526"))
  95. self.noBackgroundView.backgroundColor(NSColor.km_init(hex: "#252526"))
  96. } else {
  97. self.backgroundView.backgroundColor(NSColor.km_init(hex: "#FAFAFA"))
  98. self.noBackgroundView.backgroundColor(NSColor.km_init(hex: "#F7F8FA"))
  99. }
  100. }
  101. deinit {
  102. self.removeNotification()
  103. }
  104. override func viewDidLoad() {
  105. super.viewDidLoad()
  106. self.setup()
  107. self.initData()
  108. self.updateLanguage()
  109. self.updateButtonState(hidden: true)
  110. self.reloadData()
  111. self.addNotification()
  112. self.updateUI()
  113. }
  114. func initData() {
  115. self.updateButtonState(hidden: true)
  116. }
  117. func setup() {
  118. self.titleLabel.font = NSFont.SFProTextSemiboldFont(14.0)
  119. // self.titleLabel.textColor = NSColor.km_init(hex: "#252629")
  120. self.titleLabel.textColor = KMAppearance.Layout.h0Color()
  121. self.opacityTitleLabel.font = NSFont.SFProTextSemiboldFont(12.0)
  122. // self.opacityTitleLabel.textColor = NSColor.km_init(hex: "#616469")
  123. self.opacityTitleLabel.textColor = KMAppearance.Layout.h0Color()
  124. self.imageBox.borderWidth = 1
  125. // self.imageBox.borderColor = NSColor.km_init(hex: "#DFE1E5")
  126. self.imageBox.cornerRadius = 4
  127. // self.imageBox.fillColor = NSColor.km_init(hex: "#FFFFFF")
  128. self.imageBox.borderColor = KMAppearance.Interactive.s0Color()
  129. self.imageBox.fillColor = KMAppearance.Layout.l1Color()
  130. self.imageBox.backgroundColor(KMAppearance.Layout.l1Color())
  131. self.alignmentView.didChange = {[unowned self] view, areasArray, boundsArray in
  132. self.changeAreasAlign(areas: areasArray, newBounds: boundsArray)
  133. }
  134. opacityVC = KMDesignSelect.init(withType: .PopButton)
  135. opacityBox.contentView = opacityVC?.view
  136. opacityBox.fillColor = KMAppearance.Layout.bgDrakColor()
  137. opacityVC?.addItems(withObjectValues: ["25%","50%","75%","100%"])
  138. opacityVC?.selectItem(at: 0)
  139. opacityVC?.delete = self
  140. opacityVC?.borderColor = KMAppearance.Interactive.s0Color()
  141. opacityVC?.borderColor_disabled = KMAppearance.Interactive.s0Color()
  142. opacityVC?.background = KMAppearance.Layout.l1Color()
  143. opacityVC?.background_hov = KMAppearance.Layout.l1Color()
  144. opacityVC?.background_focus = KMAppearance.Layout.l1Color()
  145. opacityVC?.background_disabled = KMAppearance.Layout.l1Color()
  146. opacityVC?.textColor = KMAppearance.Layout.h1Color()
  147. opacityVC?.textColor_hov = KMAppearance.Layout.h1Color()
  148. opacityVC?.textColor_focus = KMAppearance.Layout.h1Color()
  149. opacityVC?.popViewControllerBackground = KMAppearance.Layout.bgColor()
  150. opacityVC?.popViewControllerTextColor = KMAppearance.Layout.h0Color()
  151. opacityVC?.popViewControllerEnterFillColor = KMAppearance.Interactive.s0Color()
  152. opacityVC?.updateUI()
  153. //alignment
  154. rotateLeftVC = KMDesignPropertySelector.init(withType: .Icon_Btn)
  155. rotateLeftBox.contentView = rotateLeftVC?.view
  156. rotateLeftBox.fillColor = NSColor.clear
  157. rotateLeftVC?.target = self
  158. rotateLeftVC?.action = #selector(leftRotationImageAction)
  159. rotateLeftVC?.image = NSImage(named: "KMImageNameEditPDFRotationLeft")!
  160. rotateLeftVC?._image_disabled = NSImage(named: "KMImageNameEditPDFRotationLeft")!
  161. rotateLeftVC?.background_hov = KMAppearance.buttonHoverColor()
  162. rotateLeftVC?.updateUI()
  163. rotateRightVC = KMDesignPropertySelector.init(withType: .Icon_Btn)
  164. rotateRightBox.contentView = rotateRightVC?.view
  165. rotateRightBox.fillColor = NSColor.clear
  166. rotateRightVC?.target = self
  167. rotateRightVC?.action = #selector(rightRotationImageAction)
  168. rotateRightVC?.image = NSImage(named: "KMImageNameEditPDFRotationRight")!
  169. rotateRightVC?.background_hov = KMAppearance.buttonHoverColor()
  170. rotateRightVC?.updateUI()
  171. flipHorizontalVC = KMDesignPropertySelector.init(withType: .Icon_Btn)
  172. flipHorizontalBox.contentView = flipHorizontalVC?.view
  173. flipHorizontalBox.fillColor = NSColor.clear
  174. flipHorizontalVC?.target = self
  175. flipHorizontalVC?.action = #selector(flipHorizontalImageAction)
  176. flipHorizontalVC?.image = NSImage(named: "KMImageNameEditPDFFlipHorizontal")!
  177. flipHorizontalVC?.background_hov = KMAppearance.buttonHoverColor()
  178. flipHorizontalVC?.updateUI()
  179. flipVerticalVC = KMDesignPropertySelector.init(withType: .Icon_Btn)
  180. flipVerticalBox.contentView = flipVerticalVC?.view
  181. flipVerticalBox.fillColor = NSColor.clear
  182. flipVerticalVC?.target = self
  183. flipVerticalVC?.action = #selector(flipVerticalImageAction)
  184. flipVerticalVC?.image = NSImage(named: "KMImageNameEditPDFFlipVertical")!
  185. flipVerticalVC?.background_hov = KMAppearance.buttonHoverColor()
  186. flipVerticalVC?.updateUI()
  187. // 设置默认状态下的滑块图像
  188. let customCell = CustomSliderCell()
  189. // 设置滑块图像
  190. customCell.knobImage = NSImage(named: "KMImageNameEditPDFSlider")
  191. // 应用自定义的NSSliderCell到NSSlider
  192. opacitySlider.cell = customCell
  193. // 添加滑动事件处理程序
  194. opacitySlider.target = self
  195. opacitySlider.action = #selector(sliderValueChanged(_:))
  196. opacitySlider.isContinuous = false
  197. cropVC = KMDesignButton.init(withType: .Text)
  198. cropBox.contentView = cropVC?.view
  199. cropBox.fillColor = NSColor.clear
  200. cropVC?.target = self
  201. cropVC?.action = #selector(cutImageAction)
  202. cropVC?.button(type: .Sec, size: .m)
  203. cropVC?.stringValue = NSLocalizedString("Crop", comment: "")
  204. cropVC?.borderColor = KMAppearance.Interactive.s0Color()
  205. cropVC?.background = KMAppearance.Layout.l1Color()
  206. cropVC?.background_hov = KMAppearance.Layout.l1Color()
  207. cropVC?.background_focus = KMAppearance.Layout.l1Color()
  208. cropVC?.textColor = KMAppearance.Layout.h1Color()
  209. cropVC?.textColor_hov = KMAppearance.Layout.h1Color()
  210. cropVC?.textColor_focus = KMAppearance.Layout.h1Color()
  211. cropVC?.updateUI()
  212. confirmVC = KMDesignButton.init(withType: .Text)
  213. confirmBox.contentView = confirmVC?.view
  214. confirmBox.fillColor = NSColor.clear
  215. confirmVC?.target = self
  216. confirmVC?.action = #selector(confirmVCImageAction)
  217. confirmVC?.button(type: .Cta, size: .m)
  218. confirmVC?.stringValue = NSLocalizedString("Confirm", comment: "")
  219. // confirmVC?.borderColor = KMAppearance.Interactive.s0Color()
  220. // confirmVC?.background = KMAppearance.Layout.l1Color()
  221. // confirmVC?.background_hov = KMAppearance.Layout.l1Color()
  222. // confirmVC?.background_focus = KMAppearance.Layout.l1Color()
  223. // confirmVC?.textColor = KMAppearance.Layout.h1Color()
  224. // confirmVC?.textColor_hov = KMAppearance.Layout.h1Color()
  225. // confirmVC?.textColor_focus = KMAppearance.Layout.h1Color()
  226. confirmVC?.updateUI()
  227. cancelVC = KMDesignButton.init(withType: .Text)
  228. cancelBox.contentView = cancelVC?.view
  229. cancelBox.fillColor = NSColor.clear
  230. cancelVC?.target = self
  231. cancelVC?.action = #selector(cancelCutImageAction)
  232. cancelVC?.button(type: .Sec, size: .m)
  233. cancelVC?.stringValue = NSLocalizedString("Cancel", comment: "")
  234. cancelVC?.borderColor = KMAppearance.Interactive.s0Color()
  235. cancelVC?.background = KMAppearance.Layout.l1Color()
  236. cancelVC?.background_hov = KMAppearance.Layout.l1Color()
  237. cancelVC?.background_focus = KMAppearance.Layout.l1Color()
  238. cancelVC?.textColor = KMAppearance.Layout.h1Color()
  239. cancelVC?.textColor_hov = KMAppearance.Layout.h1Color()
  240. cancelVC?.textColor_focus = KMAppearance.Layout.h1Color()
  241. cancelVC?.updateUI()
  242. replaceVC = KMDesignButton.init(withType: .Text)
  243. replaceBox.contentView = replaceVC?.view
  244. replaceBox.fillColor = NSColor.clear
  245. replaceVC?.target = self
  246. replaceVC?.action = #selector(replaceImageAction)
  247. replaceVC?.button(type: .Sec, size: .m)
  248. replaceVC?.stringValue = NSLocalizedString("Replace", comment: "")
  249. replaceVC?.borderColor = KMAppearance.Interactive.s0Color()
  250. replaceVC?.borderColor_hov = KMAppearance.Interactive.s0Color()
  251. replaceVC?.borderColor_disabled = KMAppearance.Interactive.s0Color()
  252. replaceVC?.background = KMAppearance.Layout.l1Color()
  253. replaceVC?.background_hov = KMAppearance.Layout.l1Color()
  254. replaceVC?.background_focus = KMAppearance.Layout.l1Color()
  255. replaceVC?.background_disabled = KMAppearance.Layout.l1Color()
  256. replaceVC?.textColor = KMAppearance.Layout.h1Color()
  257. replaceVC?.textColor_hov = KMAppearance.Layout.h1Color()
  258. replaceVC?.textColor_focus = KMAppearance.Layout.h1Color()
  259. replaceVC?.updateUI()
  260. exportVC = KMDesignButton.init(withType: .Text)
  261. exportBox.contentView = exportVC?.view
  262. exportBox.fillColor = NSColor.clear
  263. exportVC?.target = self
  264. exportVC?.action = #selector(exportImageAction)
  265. exportVC?.button(type: .Sec, size: .m)
  266. exportVC?.stringValue = NSLocalizedString("Export", comment: "")
  267. exportVC?.borderColor = KMAppearance.Interactive.s0Color()
  268. exportVC?.borderColor_hov = KMAppearance.Interactive.s0Color()
  269. exportVC?.borderColor_disabled = KMAppearance.Interactive.s0Color()
  270. exportVC?.background = KMAppearance.Layout.l1Color()
  271. exportVC?.background_hov = KMAppearance.Layout.l1Color()
  272. exportVC?.background_focus = KMAppearance.Layout.l1Color()
  273. exportVC?.background_disabled = KMAppearance.Layout.l1Color()
  274. exportVC?.textColor = KMAppearance.Layout.h1Color()
  275. exportVC?.textColor_hov = KMAppearance.Layout.h1Color()
  276. exportVC?.textColor_focus = KMAppearance.Layout.h1Color()
  277. exportVC?.updateUI()
  278. self.noTitleLabel.textColor = KMAppearance.Layout.h1Color()
  279. self.noTitleLabel.font = NSFont.SFProTextRegularFont(14)
  280. self.noImageView.image = NSImage(named: "No_addimage")
  281. self.noImageView.alphaValue = 0.4
  282. // self.noSubtitleLabel.stringValue = NSLocalizedString("Add Image", comment: "")
  283. let string = self.noSubtitleLabel.stringValue
  284. let paragraphStyle = NSMutableParagraphStyle()
  285. paragraphStyle.lineHeightMultiple = 1.32
  286. paragraphStyle.alignment = .center
  287. self.noSubtitleLabel.attributedStringValue = NSMutableAttributedString(string: NSLocalizedString(string, comment: ""), attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle, .foregroundColor : NSColor.km_init(hex: "#94989C"), NSAttributedString.Key.font: NSFont.SFProTextRegularFont(12.0)])
  288. self.noBackgroundView.backgroundColor(NSColor.km_init(hex: "#F7F8FA"))
  289. }
  290. func updateLanguage() {
  291. let areas = self.editingAreas
  292. if imagesAreas.count > 0 && imagesAreas.count != areas.count { //多选图片跟文字
  293. self.titleLabel.stringValue = NSLocalizedString("General Properties", comment: "")
  294. } else {
  295. self.titleLabel.stringValue = NSLocalizedString("Image", comment: "")
  296. }
  297. self.noTitleLabel.stringValue = NSLocalizedString("Add Image", comment: "")
  298. self.opacityTitleLabel.stringValue = NSLocalizedString("Opacity", comment: "")
  299. self.cropVC?.stringValue = NSLocalizedString("Crop", comment: "")
  300. self.confirmVC?.stringValue = NSLocalizedString("Confirm", comment: "")
  301. self.cancelVC?.stringValue = NSLocalizedString("Cancel", comment: "")
  302. self.replaceVC?.stringValue = NSLocalizedString("Replace", comment: "")
  303. self.exportVC?.stringValue = NSLocalizedString("Export", comment: "")
  304. }
  305. func reloadData() {
  306. imagesAreas = []
  307. if self.editingAreas.count > 0 {
  308. self.noBackgroundView.isHidden = true
  309. let areas = self.editingAreas
  310. self.alignmentView.editingAreas = areas
  311. for i in 0 ... areas.count-1 {
  312. if areas[i] is CPDFEditImageArea {
  313. imagesAreas.append(areas[i] as! CPDFEditImageArea)
  314. }
  315. }
  316. if imagesAreas.count == 1 && imagesAreas.count == areas.count{ //单个图片
  317. self.listView.selectImageAreas = imagesAreas.first
  318. self.headerBox.isHidden = false
  319. self.headerBoxHeight.constant = 176
  320. self.headerBoxMaginWidthConstraint.constant = 8
  321. self.imageBox.isHidden = false
  322. self.imageBoxHeight.constant = 88
  323. self.opacityBox.isHidden = false
  324. self.opacityBoxHeight.constant = 56
  325. self.opacityBoxBottomMaginConstraint.constant = 16
  326. self.opacityBoxTopConstraint.constant = 16
  327. self.buttonBox.isHidden = false
  328. // self.cropBox.isHidden = false
  329. // self.cancelBox.isHidden = false
  330. // self.replaceBox.isHidden = false
  331. self.buttonBoxHeight.constant = 112
  332. self.editImageView.image = self.listView.selectImageAreas.thumbnailImage
  333. self.alignmentViewTopConstraint.constant = 16
  334. let opacity: CGFloat = self.listView.opacity(for: imagesAreas.first)
  335. self.updateImageAreasOpacity(opacity: opacity, state: .ended, needListView: false)
  336. } else if imagesAreas.count > 1 && imagesAreas.count == areas.count { //多选图片
  337. self.headerBox.isHidden = false
  338. self.headerBoxHeight.constant = 82
  339. self.headerBoxMaginWidthConstraint.constant = 0
  340. self.imageBox.isHidden = true
  341. self.imageBoxHeight.constant = 0
  342. self.opacityBox.isHidden = false
  343. self.opacityBoxHeight.constant = 56
  344. self.opacityBoxBottomMaginConstraint.constant = 0
  345. self.opacityBoxTopConstraint.constant = 0
  346. self.buttonBox.isHidden = false
  347. // self.cropBox.isHidden = true
  348. // self.cancelBox.isHidden = true
  349. // self.replaceBox.isHidden = true
  350. self.buttonBoxHeight.constant = 0
  351. self.alignmentViewTopConstraint.constant = 16
  352. var opacity = self.listView.opacity(for: imagesAreas.first)
  353. for area in imagesAreas {
  354. let newOpacity = self.listView.opacity(for: area)
  355. if (opacity < newOpacity) {
  356. opacity = newOpacity
  357. }
  358. }
  359. self.updateImageAreasOpacity(opacity: opacity, state: .ended, needListView: false)
  360. } else if imagesAreas.count > 0 && imagesAreas.count != areas.count { //多选图片跟文字
  361. self.opacityBoxBottomMaginConstraint.constant = 0
  362. self.headerBoxMaginWidthConstraint.constant = 0
  363. self.alignmentViewTopConstraint.constant = 0
  364. self.opacityBoxTopConstraint.constant = 0
  365. // self.headerBox.isHidden = true
  366. self.headerBoxHeight.constant = 48
  367. self.imageBox.isHidden = true
  368. self.imageBoxHeight.constant = 0
  369. self.opacityBox.isHidden = true
  370. self.opacityBoxHeight.constant = 0
  371. self.buttonBox.isHidden = true
  372. self.buttonBoxHeight.constant = 0
  373. }
  374. self.updateLanguage()
  375. } else {
  376. // self.updateButtonState(hidden: true)
  377. // self.editImageView.image = NSImage()
  378. self.noBackgroundView.isHidden = false
  379. }
  380. }
  381. func updateButtonState(hidden: Bool) {
  382. if hidden {
  383. self.cancelBox.isHidden = true
  384. self.confirmBox.isHidden = true
  385. self.cropBox.isHidden = false
  386. self.replaceVC?.enabled = true
  387. self.exportVC?.enabled = true
  388. self.opacitySlider.isEnabled = true
  389. self.opacityVC?.enabled = true
  390. self.rotateLeftVC?.button.isEnabled = true
  391. self.rotateLeftVC?.view.alphaValue = 1.0
  392. self.rotateRightVC?.button.isEnabled = true
  393. self.rotateRightVC?.view.alphaValue = 1.0
  394. self.flipVerticalVC?.button.isEnabled = true
  395. self.flipVerticalVC?.view.alphaValue = 1.0
  396. self.flipHorizontalVC?.button.isEnabled = true
  397. self.flipHorizontalVC?.view.alphaValue = 1.0
  398. } else {
  399. self.cancelBox.isHidden = false
  400. self.confirmBox.isHidden = false
  401. self.cropBox.isHidden = true
  402. self.replaceVC?.enabled = false
  403. self.exportVC?.enabled = false
  404. self.opacitySlider.isEnabled = false
  405. self.opacityVC?.enabled = false
  406. self.rotateLeftVC?.button.isEnabled = false
  407. self.rotateLeftVC?.view.alphaValue = 0.5
  408. self.rotateRightVC?.button.isEnabled = false
  409. self.rotateRightVC?.view.alphaValue = 0.5
  410. self.flipVerticalVC?.button.isEnabled = false
  411. self.flipVerticalVC?.view.alphaValue = 0.5
  412. self.flipHorizontalVC?.button.isEnabled = false
  413. self.flipHorizontalVC?.view.alphaValue = 0.5
  414. }
  415. self.reloadData()
  416. if self.noBackgroundView.isHidden == false {
  417. self.opacityVC?.enabled = false
  418. }
  419. }
  420. func updateImageAreasOpacity(opacity: CGFloat, state: KMOperationState, needListView: Bool = true) {
  421. if self.editingAreas.count >= 1 {
  422. if needListView {
  423. for area in imagesAreas {
  424. self.listView.setOpacityEditArea(area, opacity: opacity)
  425. }
  426. }
  427. // self.listView.editingAreas()!.count == 1 &&
  428. if (self.listView.editingAreas()?.first is CPDFEditImageArea) {
  429. self.listView.selectImageAreas = self.listView.editingAreas()!.first as? CPDFEditImageArea
  430. self.editImageView.image = self.listView.selectImageAreas.thumbnailImage
  431. self.opacitySlider.objectValue = self.listView.opacity(for: self.listView.selectImageAreas)
  432. self.opacityVC?.stringValue = Int(opacity * 100).description + "%"
  433. self.editImageView.alphaValue = opacity
  434. }
  435. }
  436. }
  437. private func changeAreasAlign(areas:[Any],newBounds:[String]) {
  438. var oldBounds : [String] = []
  439. for i in 0 ... areas.count-1 {
  440. let area : CPDFEditArea = areas[i] as! CPDFEditArea
  441. oldBounds.append(NSStringFromRect(area.bounds))
  442. self.listView.setBoundsEditArea(area, withBounds: NSRectFromString(newBounds[i]))
  443. }
  444. self.listView.setNeedsDisplayForVisiblePages()
  445. }
  446. }
  447. extension KMEditImagePropertyViewController: KMSelectPopButtonDelegate {
  448. func km_comboBoxSelectionDidChange(_ obj: KMDesignSelect) {
  449. if obj == opacityVC {
  450. KMPrint("km_comboBoxSelectionDidChange")
  451. let index = obj.indexOfSelectedItem
  452. var string = obj.items[index]
  453. string = string.replacingOccurrences(of: "%", with: "")
  454. let value = CGFloat(Float(string)! * 0.01)
  455. self.updateImageAreasOpacity(opacity: value, state: .changed)
  456. }
  457. }
  458. func km_controlTextDidEndEditing(_ obj: KMDesignSelect) {
  459. if obj == opacityVC {
  460. KMPrint("km_comboBoxSelectionDidChange")
  461. let index = obj.indexOfSelectedItem
  462. var string = obj.items[index]
  463. string = string.replacingOccurrences(of: "%", with: "")
  464. let value = CGFloat(Float(string)! * 0.01)
  465. self.updateImageAreasOpacity(opacity: value, state: .ended)
  466. }
  467. }
  468. }
  469. //MARK: - Action
  470. extension KMEditImagePropertyViewController {
  471. @objc func sliderValueChanged(_ sender: NSSlider) {
  472. let sliderValue = sender.floatValue
  473. self.updateImageAreasOpacity(opacity:CGFloat(sliderValue), state: .changed)
  474. }
  475. @IBAction func rightRotationImageAction(_ sender: Any) {
  476. if self.listView.editingAreas()?.count ?? 0 < 1 {
  477. return
  478. }
  479. FMTrackEventManager.defaultManager.trackEvent(event: "SubTbr_PageEdit", withProperties: ["SubTbr_Btn": "Btn_SubTbr_PageEdit_Rotate"])
  480. let areas = self.listView.editingAreas()
  481. if areas!.count == 1 && (areas!.first is CPDFEditImageArea) {
  482. let imageArea = areas!.first as! CPDFEditImageArea
  483. self.listView.rotate(with: imageArea, rotate: 90)
  484. self.listView.selectImageAreas = imageArea
  485. self.editImageView.image = self.listView.selectImageAreas.thumbnailImage
  486. } else if areas!.count > 1 {
  487. for imagesArea in imagesAreas {
  488. self.listView.rotate(with: imagesArea, rotate: 90)
  489. }
  490. }
  491. self.delegate?.editImagePropertyViewControllerDidChanged(controller: self, type: .rotate)
  492. }
  493. @IBAction func leftRotationImageAction(_ sender: Any) {
  494. if self.listView.editingAreas()?.count ?? 0 < 1 {
  495. return
  496. }
  497. FMTrackEventManager.defaultManager.trackEvent(event: "SubTbr_PageEdit", withProperties: ["SubTbr_Btn": "Btn_SubTbr_PageEdit_Rotate"])
  498. let areas = self.listView.editingAreas()
  499. if areas!.count == 1 && (areas!.first is CPDFEditImageArea) {
  500. self.listView.rotate(with: self.listView.selectImageAreas, rotate: -90)
  501. if self.listView.editingAreas()!.count == 1 && (self.listView.editingAreas()!.first is CPDFEditImageArea) {
  502. self.listView.selectImageAreas = self.listView.editingAreas()!.first as? CPDFEditImageArea
  503. }
  504. self.editImageView.image = self.listView.selectImageAreas.thumbnailImage
  505. } else {
  506. for imagesArea in imagesAreas {
  507. self.listView.rotate(with: imagesArea, rotate: -90)
  508. }
  509. }
  510. self.delegate?.editImagePropertyViewControllerDidChanged(controller: self, type: .rotate)
  511. }
  512. @IBAction func flipHorizontalImageAction(_ sender: Any) {
  513. if self.listView.editingAreas()?.count ?? 0 < 1 {
  514. return
  515. }
  516. FMTrackEventManager.defaultManager.trackEvent(event: "SubTbr_PageEdit", withProperties: ["SubTbr_Btn": "Btn_SubTbr_PageEdit_Reverse"])
  517. let areas = self.listView.editingAreas()
  518. if areas != nil {
  519. for item in areas! {
  520. if item is CPDFEditImageArea {
  521. self.listView.horizontalMirror(with: item as? CPDFEditImageArea)
  522. if areas?.count == 1 {
  523. self.editImageView.image = (item as AnyObject).thumbnailImage
  524. }
  525. } else {
  526. for imagesArea in imagesAreas {
  527. self.listView.horizontalMirror(with: imagesArea)
  528. }
  529. }
  530. }
  531. }
  532. self.delegate?.editImagePropertyViewControllerDidChanged(controller: self, type: .flip)
  533. }
  534. @IBAction func flipVerticalImageAction(_ sender: Any) {
  535. if self.listView.editingAreas()?.count ?? 0 < 1 {
  536. return
  537. }
  538. FMTrackEventManager.defaultManager.trackEvent(event: "SubTbr_PageEdit", withProperties: ["SubTbr_Btn": "Btn_SubTbr_PageEdit_Reverse"])
  539. let areas = self.listView.editingAreas()
  540. if areas != nil {
  541. for item in areas! {
  542. if item is CPDFEditImageArea {
  543. self.listView.verticalMirror(with: item as? CPDFEditImageArea)
  544. self.editImageView.image = self.listView.selectImageAreas.thumbnailImage
  545. } else {
  546. for imagesArea in imagesAreas {
  547. self.listView.verticalMirror(with: imagesArea)
  548. }
  549. }
  550. }
  551. }
  552. self.delegate?.editImagePropertyViewControllerDidChanged(controller: self, type: .flip)
  553. }
  554. @IBAction func cutImageAction(_ sender: Any) {
  555. if self.listView.selectImageAreas == nil {
  556. return
  557. }
  558. self.listView.isEditImage = true
  559. self.listView.enterCrop(with: self.listView.selectImageAreas)
  560. self.updateButtonState(hidden: false)
  561. }
  562. @IBAction func confirmVCImageAction(_ sender: Any) {
  563. if self.listView.selectImageAreas == nil || self.listView.cropAreas == nil {
  564. return
  565. }
  566. self.listView.cropEditImageArea(self.listView.selectImageAreas, withBounds: self.listView.cropAreas.cropRect)
  567. self.cancelCutImageAction(cancelVC?.button as Any)
  568. }
  569. @IBAction func cancelCutImageAction(_ sender: Any) {
  570. if self.listView.selectImageAreas == nil {
  571. return
  572. }
  573. self.listView.exitCrop(with: self.listView.selectImageAreas)
  574. self.listView.cropAreas = nil
  575. self.listView.isEditImage = false
  576. self.updateButtonState(hidden: true)
  577. }
  578. @IBAction func restoreCutImageAction(_ sender: Any) {
  579. if self.listView.selectImageAreas == nil {
  580. return
  581. }
  582. self.listView.resetCrop(with: self.listView.selectImageAreas)
  583. }
  584. @IBAction func replaceImageAction(_ sender: NSButton) {
  585. if self.listView.selectImageAreas == nil {
  586. return
  587. }
  588. FMTrackEventManager.defaultManager.trackEvent(event: "SubTbr_PageEdit", withProperties: ["SubTbr_Btn": "Btn_SubTbr_PageEdit_Replace"])
  589. let panel = NSOpenPanel()
  590. panel.allowsMultipleSelection = false
  591. panel.allowedFileTypes = ["png","jpg"]
  592. panel.beginSheetModal(for: NSApp.mainWindow!) { response in
  593. if response == .OK {
  594. let openPath = panel.url?.path
  595. // let s = self.listView.extractImage(with: self.selectImageAreas, toImagePath: openPath!)
  596. let s = self.listView.replace(self.listView.selectImageAreas, imagePath: openPath!)
  597. if s {
  598. }
  599. }
  600. }
  601. }
  602. // @available(macOS 13.0, *)
  603. @IBAction func exportImageAction(_ sender: Any) {
  604. if self.listView.selectImageAreas == nil {
  605. return
  606. }
  607. if imagesAreas.count == 1 {
  608. let panel = NSSavePanel()
  609. panel.nameFieldStringValue = "\(NSLocalizedString("Untitled", comment: "")).jpg"
  610. // let button = NSButton.init(checkboxWithTitle: NSLocalizedString("Open the document after saving", comment: ""), target: nil, action: nil)
  611. // button.state = .on
  612. // panel.accessoryView = button
  613. panel.isExtensionHidden = true
  614. let response = panel.runModal()
  615. if response == .OK {
  616. let url = panel.url
  617. if FileManager.default.fileExists(atPath: url!.path) {
  618. try?FileManager.default.removeItem(atPath: url!.path)
  619. }
  620. let result = self.listView.extractImage(with: self.listView.selectImageAreas, toImagePath: url!.path)
  621. if result {
  622. // if button.state == .on { /// 开启文档
  623. // NSWorkspace.shared.openFile(url!.path)
  624. NSWorkspace.shared.activateFileViewerSelecting([url!])
  625. // } else {
  626. //
  627. // }
  628. }
  629. }
  630. } else if imagesAreas.count > 1 {
  631. let panel = NSOpenPanel()
  632. panel.canChooseFiles = false
  633. panel.canChooseDirectories = true
  634. panel.canCreateDirectories = true
  635. panel.allowsMultipleSelection = false
  636. panel.beginSheetModal(for: NSApp.mainWindow!) { response in
  637. if response == .OK {
  638. let outputURL = panel.url
  639. let s = self.listView.document.documentURL.lastPathComponent
  640. let folderPath = self.listView.document.documentURL.deletingPathExtension().lastPathComponent + "_extract"
  641. var filePath = outputURL?.path.stringByAppendingPathComponent(folderPath)
  642. var i = 1
  643. let testFilePath = filePath
  644. while FileManager.default.fileExists(atPath: filePath!) {
  645. filePath = testFilePath! + "\(i)"
  646. i = i + 1
  647. }
  648. try? FileManager.default.createDirectory(atPath: filePath!, withIntermediateDirectories: false, attributes: nil)
  649. var saveURLs : [URL] = []
  650. for j in 0 ... self.imagesAreas.count-1 {
  651. let documentFileName = self.listView.document.documentURL.deletingPathExtension().lastPathComponent
  652. var outPath = filePath!
  653. outPath = outPath.stringByAppendingPathComponent(documentFileName)
  654. outPath = outPath + "page \(j+1)"
  655. outPath = outPath.stringByAppendingPathExtension("jpg")
  656. let result = self.listView.extractImage(with: self.imagesAreas[j], toImagePath: outPath)
  657. if result {
  658. saveURLs.append(URL(fileURLWithPath: outPath))
  659. }
  660. }
  661. NSWorkspace.shared.activateFileViewerSelecting(saveURLs)
  662. }
  663. }
  664. }
  665. }
  666. }
  667. class CustomSliderCell: NSSliderCell {
  668. var knobImage: NSImage?
  669. override func drawKnob(_ knobRect: NSRect) {
  670. if let image = knobImage {
  671. let imageSize = NSSize(width: knobRect.size.height, height: knobRect.size.height)
  672. let imageRect = NSRect(origin: knobRect.origin, size: imageSize)
  673. image.draw(in: imageRect)
  674. } else {
  675. super.drawKnob(knobRect)
  676. }
  677. }
  678. }