KMBackgroundPropertyController.swift 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. //
  2. // KMBackgroundPropertyController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by Niehaoyu on 2024/11/6.
  6. //
  7. import Cocoa
  8. import KMComponentLibrary
  9. @objc protocol KMBackgroundPropertyControllerDelegate: AnyObject {
  10. //水印数据有更新
  11. @objc optional func backgroundPropertyControllerDidUpdate(_ controller: KMBackgroundPropertyController)
  12. //切换到模板界面
  13. @objc optional func backgroundPropertyControllerDidChangetoTemplate(_ controller: KMBackgroundPropertyController)
  14. //成功保存到模板
  15. @objc optional func backgroundPropertyControllerSaveTemplateSuccess(_ controller: KMBackgroundPropertyController, _ data: KMBackgroundModel)
  16. //取消修改模板信息
  17. @objc optional func backgroundPropertyControllerCancelTemplateEdit(_ controller: KMBackgroundPropertyController)
  18. @objc optional func backgroundPropertyControllerFinishTemplateEdit(_ controller: KMBackgroundPropertyController)
  19. }
  20. class KMBackgroundPropertyController: NSViewController {
  21. @IBOutlet var contendView: NSView!
  22. @IBOutlet var leftTopButton: ComponentButton!
  23. @IBOutlet var titleLabel: NSTextField!
  24. @IBOutlet var templateButton: ComponentButton!
  25. @IBOutlet var typeTabsBGView: NSView!
  26. @IBOutlet var typeTabs: ComponentTabs!
  27. @IBOutlet var infoContendView: NSView!
  28. @IBOutlet var infoContendTopConst: NSLayoutConstraint!
  29. //Text
  30. @IBOutlet var textBGView: NSView!
  31. @IBOutlet var colorLabel: NSTextField!
  32. @IBOutlet var fontColorGroup: ComponentCColorGroup!
  33. //File
  34. @IBOutlet var fileBGView: NSView!
  35. @IBOutlet var fileInputView: ComponentInput!
  36. @IBOutlet var fileInputAddonView: ComponentInputAddon!
  37. //Appearance
  38. @IBOutlet var appearanceBGView: NSView!
  39. @IBOutlet var appearanceLabel: NSTextField!
  40. @IBOutlet var appearance_RotateSelect: ComponentSelect!
  41. @IBOutlet var appearance_OpacitySelect: ComponentSelect!
  42. @IBOutlet var appearanceScaleCheckbox: ComponentCheckBox!
  43. @IBOutlet var appearanceScaleSelect: ComponentSelect!
  44. @IBOutlet var appearanceBGTopConst: NSLayoutConstraint!
  45. //Position
  46. @IBOutlet var positionBGView: NSView!
  47. @IBOutlet var positionLabel: NSTextField!
  48. @IBOutlet var positionItemView: ComponentCPosition!
  49. @IBOutlet var positionXInput: ComponentInputNumber!
  50. @IBOutlet var positionYInput: ComponentInputNumber!
  51. //Save
  52. @IBOutlet var saveTemplateBGView: NSView!
  53. @IBOutlet var saveButton: ComponentButton!
  54. private var textTabProperty = ComponentTabsProperty(tabsType: .underline_Fill, state: .normal, showIcon: false, title: KMLocalizedString("Color"))
  55. private var fileTabProperty = ComponentTabsProperty(tabsType: .underline_Fill, state: .normal, showIcon: false, title: KMLocalizedString("File"))
  56. weak open var delegate: KMBackgroundPropertyControllerDelegate?
  57. var originalDataDict: Dictionary<String, Any>?
  58. var backgroundData: KMBackgroundModel = KMBackgroundModel()
  59. var editSubType: KMPDFEditSubModeType = .none
  60. //MARK: - func
  61. override func viewDidLoad() {
  62. super.viewDidLoad()
  63. // Do view setup here.
  64. setupProperty()
  65. }
  66. func setupProperty() {
  67. contendView.wantsLayer = true
  68. contendView.layer?.backgroundColor = ComponentLibrary.shared.getComponentColorFromKey("colorBg/layout-middle").cgColor
  69. titleLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2")
  70. titleLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-m-bold")
  71. leftTopButton.properties = ComponentButtonProperty(type: .text_gray, size: .xxs, onlyIcon: true, icon: NSImage(named: "watermark_arrowLeft"), keepPressState: false)
  72. leftTopButton.setTarget(self, action: #selector(leftTopButtonClicked(_:)))
  73. templateButton.properties = ComponentButtonProperty(type: .text_gray, size: .xxs, onlyIcon: true, icon: NSImage(named: "icon_wm_template"), keepPressState: false)
  74. templateButton.setTarget(self, action: #selector(templateButtonClicked(_:)))
  75. typeTabs.updateItemProperty([textTabProperty, fileTabProperty])
  76. typeTabs.delegate = self
  77. //Text
  78. let colorAProperty = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: false, color: KMBackgroundModel.defaultColors()[0])
  79. let colorBProperty = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: false, color: KMBackgroundModel.defaultColors()[1])
  80. let colorCProperty = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: false, color: KMBackgroundModel.defaultColors()[2])
  81. let colorDProperty = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: false, color: KMBackgroundModel.defaultColors()[3])
  82. let colorEProperty = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: true, color: KMBackgroundModel.defaultColors()[4])
  83. fontColorGroup.setUpWithColorPropertys([colorAProperty, colorBProperty, colorCProperty, colorDProperty], customItemProperty: colorEProperty)
  84. fontColorGroup.delegate = self
  85. //File
  86. fileInputView.properties = ComponentInputProperty(size: .s,
  87. state:.pressed ,
  88. placeholder: "Select Source File...",
  89. text: "",
  90. creatable: false)
  91. fileInputView.properties.propertyInfo.cornerRadius_topLeft = 0
  92. fileInputView.properties.propertyInfo.cornerRadius_topRight = 0
  93. fileInputView.properties.propertyInfo.cornerRadius_bottomLeft = 0
  94. fileInputView.properties.propertyInfo.cornerRadius_bottomRight = 0
  95. fileInputView.reloadData()
  96. fileInputAddonView.properties = ComponentInputAddonProperty(size: .s,
  97. state: .normal,
  98. addOnBefore: false,
  99. onlyRead: false,
  100. addonType: .imageWithColor,
  101. iconImage: NSImage(named: "icon_folder"))
  102. fileInputAddonView.setTarget(self, action: #selector(chooseURLAction(_ :)))
  103. //Appearance
  104. appearanceLabel.stringValue = KMLocalizedString("Appearance")
  105. appearanceLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2")
  106. appearanceLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium")
  107. appearance_RotateSelect.properties = ComponentSelectProperties(size: .s,
  108. state: .normal,
  109. creatable: true,
  110. text: "0°",
  111. textUnit: "°",
  112. regexString: "0123456789-")
  113. var rotateItems: [ComponentMenuitemProperty] = []
  114. for string in ["0°", "45°", "-45°", "90°", "-90°"] {
  115. let item = ComponentMenuitemProperty(type: .normal, text: string)
  116. rotateItems.append(item)
  117. }
  118. appearance_RotateSelect.updateMenuItemsArr(rotateItems)
  119. appearance_RotateSelect.delegate = self
  120. appearance_OpacitySelect.properties = ComponentSelectProperties(size: .s,
  121. state: .normal,
  122. creatable: true,
  123. text: "100%",
  124. textUnit: "%",
  125. regexString: "0123456789")
  126. var opacityItems: [ComponentMenuitemProperty] = []
  127. for string in ["25%", "50%", "75%", "100%"] {
  128. let item = ComponentMenuitemProperty(type: .normal, text: string)
  129. opacityItems.append(item)
  130. }
  131. appearance_OpacitySelect.updateMenuItemsArr(opacityItems)
  132. appearance_OpacitySelect.delegate = self
  133. appearanceScaleCheckbox.properties = ComponentCheckBoxProperty(size: .s, text: KMLocalizedString("Scale relative to target page"), checkboxType: .normal)
  134. appearanceScaleCheckbox.setTarget(self, action: #selector(checkBoxClicked(_:)))
  135. appearanceScaleSelect.properties = ComponentSelectProperties(size: .s,
  136. state: .normal,
  137. creatable: true,
  138. text: "100%",
  139. textUnit: "%",
  140. regexString: "0123456789")
  141. var appearanceScaleItems: [ComponentMenuitemProperty] = []
  142. for string in ["25%", "50%", "75%", "100%", "125%", "150%","200%"] {
  143. let item = ComponentMenuitemProperty(type: .normal, text: string)
  144. appearanceScaleItems.append(item)
  145. }
  146. appearanceScaleSelect.updateMenuItemsArr(appearanceScaleItems)
  147. appearanceScaleSelect.delegate = self
  148. //Position
  149. positionLabel.stringValue = KMLocalizedString("Position (mm)")
  150. positionLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2")
  151. positionLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium")
  152. positionItemView.properties = ComponentCPositionProperty(rowCount: 3, columnCount: 3, dash: false, selRow: 1, selColumn: 1)
  153. positionItemView.delegate = self
  154. positionXInput.properties = ComponentInputNumberProperty(alignment: .left,
  155. size: .s,
  156. minSize: -1000,
  157. maxSize: 1000,
  158. text: "0")
  159. positionXInput.delegate = self
  160. positionYInput.properties = ComponentInputNumberProperty(alignment: .left,
  161. size: .s,
  162. minSize: -1000,
  163. maxSize: 1000,
  164. text: "0")
  165. positionYInput.delegate = self
  166. //Save
  167. saveTemplateBGView.wantsLayer = true
  168. saveTemplateBGView.layer?.backgroundColor = ComponentLibrary.shared.getComponentColorFromKey("colorBg/layout-middle").cgColor
  169. saveButton.properties = ComponentButtonProperty(type: .default_tertiary, size: .m, showLeftIcon: true, buttonText: KMLocalizedString("Save as Template"), icon: NSImage(named: "icon_wm_template_save"), keepPressState: false)
  170. saveButton.setTarget(self, action: #selector(saveButtonClicked(_:)))
  171. }
  172. func reloadData() {
  173. titleLabel.stringValue = KMLocalizedString("Add Background")
  174. leftTopButton.isHidden = true
  175. saveTemplateBGView.isHidden = false
  176. templateButton.properties.icon = NSImage(named: "icon_wm_template")
  177. templateButton.properties.isDisabled = false
  178. infoContendTopConst.constant = 56
  179. typeTabsBGView.isHidden = false
  180. if editSubType == .edit {
  181. infoContendTopConst.constant = 8
  182. typeTabsBGView.isHidden = true
  183. titleLabel.stringValue = KMLocalizedString("Edit Background")
  184. leftTopButton.isHidden = false
  185. saveTemplateBGView.isHidden = true
  186. templateButton.properties.icon = NSImage(named: "edit_save")
  187. if backgroundData.type == .image {
  188. if backgroundData.imagePath == nil {
  189. templateButton.properties.isDisabled = true
  190. }
  191. }
  192. }
  193. templateButton.reloadData()
  194. fileBGView.isHidden = true
  195. textBGView.isHidden = true
  196. textTabProperty.state = .normal
  197. fileTabProperty.state = .normal
  198. if backgroundData.type == .color {
  199. textBGView.isHidden = false
  200. appearanceBGTopConst.constant = 88
  201. textTabProperty.state = .pressed
  202. } else if backgroundData.type == .image {
  203. fileBGView.isHidden = false
  204. appearanceBGTopConst.constant = 48
  205. fileTabProperty.state = .pressed
  206. }
  207. typeTabs.refreshItems()
  208. //Text
  209. fontColorGroup.currentColor = backgroundData.color
  210. fontColorGroup.refreshUI()
  211. //File
  212. fileInputView.properties.text = backgroundData.imagePath ?? ""
  213. fileInputView.reloadData()
  214. //Appearance
  215. appearance_RotateSelect.properties.text = String(format: "%.0f", backgroundData.rotation) + "°"
  216. appearance_RotateSelect.reloadData()
  217. if backgroundData.opacity > 1 {
  218. backgroundData.opacity = 1
  219. }
  220. appearance_OpacitySelect.properties.text = String(format: "%.0f", backgroundData.opacity*100) + "%"
  221. appearance_OpacitySelect.reloadData()
  222. appearanceScaleCheckbox.properties.checkboxType = backgroundData.isScale ? .selected : .normal
  223. appearanceScaleCheckbox.reloadData()
  224. appearanceScaleSelect.properties.isDisabled = backgroundData.isScale ? false : true
  225. appearanceScaleSelect.properties.text = String(format: "%.0f", backgroundData.scale*100) + "%"
  226. appearanceScaleSelect.reloadData()
  227. //Position
  228. if backgroundData.verticalMode == 2 {
  229. positionItemView.properties.selRow = 0
  230. } else if backgroundData.verticalMode == 1 {
  231. positionItemView.properties.selRow = 1
  232. } else if backgroundData.verticalMode == 0 {
  233. positionItemView.properties.selRow = 2
  234. }
  235. if backgroundData.horizontalMode == 0 {
  236. positionItemView.properties.selColumn = 0
  237. } else if backgroundData.horizontalMode == 1 {
  238. positionItemView.properties.selColumn = 1
  239. } else if backgroundData.horizontalMode == 2 {
  240. positionItemView.properties.selColumn = 2
  241. }
  242. positionItemView.reloadData()
  243. positionXInput.properties.text = String(format: "%.0f", backgroundData.horizontalSpace)
  244. positionXInput.reloadData()
  245. positionYInput.properties.text = String(format: "%.0f", backgroundData.verticalSpace)
  246. positionYInput.reloadData()
  247. if backgroundData.type == .color {
  248. saveButton.properties.isDisabled = false
  249. } else if backgroundData.type == .image {
  250. if backgroundData.imagePath != nil {
  251. saveButton.properties.isDisabled = false
  252. } else {
  253. saveButton.properties.isDisabled = true
  254. }
  255. }
  256. saveButton.reloadData()
  257. }
  258. //MARK: - Action
  259. @objc func leftTopButtonClicked(_ sender: ComponentButton) {
  260. if sender == leftTopButton {
  261. var isChanged = false
  262. if let dict = self.originalDataDict {
  263. isChanged = KMBackgroundManager.compareIsChangedModel(backgroundData, withDict: dict as NSDictionary)
  264. }
  265. if isChanged == true {
  266. let alert = NSAlert()
  267. alert.alertStyle = .critical
  268. alert.messageText = KMLocalizedString("Save template changes?")
  269. alert.informativeText = KMLocalizedString("Cancel and they will not be saved.")
  270. alert.addButton(withTitle: KMLocalizedString("Save"))
  271. alert.addButton(withTitle: KMLocalizedString("Cancel"))
  272. alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in
  273. if response == NSApplication.ModalResponse.alertFirstButtonReturn {
  274. let _ = KMBackgroundManager.defaultManager.updateTemplate(model: self.backgroundData)
  275. self.delegate?.backgroundPropertyControllerFinishTemplateEdit?(self)
  276. } else {
  277. if let dict = self.originalDataDict {
  278. KMBackgroundManager.defaultManager.updateModel(self.backgroundData, withDict: dict as NSDictionary)
  279. let _ = KMBackgroundManager.defaultManager.updateTemplate(model: self.backgroundData)
  280. }
  281. self.delegate?.backgroundPropertyControllerFinishTemplateEdit?(self)
  282. }
  283. }
  284. } else {
  285. delegate?.backgroundPropertyControllerCancelTemplateEdit?(self)
  286. }
  287. }
  288. }
  289. @objc func templateButtonClicked(_ sender: ComponentButton) {
  290. if editSubType == .add {
  291. delegate?.backgroundPropertyControllerDidChangetoTemplate?(self)
  292. } else if editSubType == .edit {
  293. let _ = KMBackgroundManager.defaultManager.updateTemplate(model: self.backgroundData)
  294. delegate?.backgroundPropertyControllerFinishTemplateEdit?(self)
  295. }
  296. }
  297. @objc func checkBoxClicked(_ sender: ComponentCheckBox) {
  298. if sender == appearanceScaleCheckbox {
  299. backgroundData.isScale = appearanceScaleCheckbox.properties.checkboxType == .selected ? true : false
  300. }
  301. reloadData()
  302. delegate?.backgroundPropertyControllerDidUpdate?(self)
  303. }
  304. @objc func saveButtonClicked(_ sender: ComponentButton) {
  305. let saveWindow: KMWatermarkSaveWindow = KMWatermarkSaveWindow(windowNibName: "KMWatermarkSaveWindow")
  306. if backgroundData.type == .color {
  307. saveWindow.nameValue = backgroundData.name
  308. } else if backgroundData.type == .image {
  309. saveWindow.nameValue = backgroundData.imagePath?.lastPathComponent ?? ""
  310. }
  311. saveWindow.saveHandler = {[weak self] string in
  312. guard let weakSelf = self else { return }
  313. DispatchQueue.main.async {
  314. weakSelf.backgroundData.name = string ?? ""
  315. if KMBackgroundManager.defaultManager.addTemplate(model: weakSelf.backgroundData) {
  316. weakSelf.delegate?.backgroundPropertyControllerSaveTemplateSuccess?(weakSelf, weakSelf.backgroundData)
  317. }
  318. }
  319. }
  320. saveWindow.own_beginSheetModal(for: view.window) { string in
  321. }
  322. }
  323. @objc func chooseURLAction(_ sender: NSView) {
  324. let openPanel = NSOpenPanel()
  325. openPanel.canChooseDirectories = false
  326. openPanel.canChooseFiles = true
  327. openPanel.allowsMultipleSelection = false
  328. openPanel.allowedFileTypes = ["jpg", "jpeg", "png", "pdf"]
  329. openPanel.beginSheetModal(for: self.view.window!) { (result) in
  330. if result == NSApplication.ModalResponse.OK {
  331. guard let url = openPanel.url else { return }
  332. let filePath = url.path
  333. let outFolder = KMBackgroundManager.defaultManager.kBackgroundImageFolder
  334. let fileName = filePath.getLastComponentDeleteExtension
  335. if filePath.extension.lowercased() == ".pdf" {
  336. let pdf = CPDFDocument(url: url)
  337. guard !pdf!.isEncrypted else { return }
  338. if let image = self.generateThumbnail(for: url) {
  339. if let outFolderPath = outFolder?.stringByAppendingPathComponent(fileName + ".png") {
  340. try?image.pngData()?.write(to: URL(fileURLWithPath: outFolderPath))
  341. if FileManager.default.fileExists(atPath: outFolderPath) {
  342. self.backgroundData.imagePath = outFolderPath
  343. self.delegate?.backgroundPropertyControllerDidUpdate?(self)
  344. self.reloadData()
  345. }
  346. }
  347. }
  348. } else {
  349. let image = NSImage(contentsOfFile: url.path)
  350. if image == nil || NSImage.isDamageImage(image, imagePath: url.path) {
  351. let alert = NSAlert()
  352. alert.alertStyle = .critical
  353. alert.messageText = "The file \"\(url.lastPathComponent)\" could not be opened."
  354. alert.informativeText = "It may be damaged or use a file format that PDF Reader Pro doesn’t recognize."
  355. alert.addButton(withTitle: "Cancel")
  356. alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in
  357. if response == NSApplication.ModalResponse.alertFirstButtonReturn {
  358. // Cancel button clicked
  359. }
  360. }
  361. return
  362. }
  363. if let resultPath = outFolder?.stringByAppendingPathComponent(fileName + ".png") {
  364. try?FileManager.default.copyItem(atPath: url.path, toPath: resultPath)
  365. self.backgroundData.imagePath = resultPath
  366. }
  367. self.delegate?.backgroundPropertyControllerDidUpdate?(self)
  368. self.reloadData()
  369. }
  370. }
  371. }
  372. }
  373. func generateThumbnail(for pdfURL: URL) -> NSImage? {
  374. // 创建PDF文档
  375. guard let pdfDocument = CGPDFDocument(pdfURL as CFURL),
  376. let pdfPage = pdfDocument.page(at: 1) else {
  377. print("打开PDF文件失败")
  378. return nil
  379. }
  380. // 获取页面尺寸
  381. let pageRect = pdfPage.getBoxRect(.mediaBox)
  382. // 创建图形上下文
  383. let size = NSSize(width: 200, height: 300)
  384. let bitsPerComponent = 8
  385. let bytesPerPixel = 4
  386. let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
  387. let context = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: bitsPerComponent, bytesPerRow: 0, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: bitmapInfo)
  388. // 绘制PDF页面
  389. context?.saveGState()
  390. context?.translateBy(x: 0, y: size.height)
  391. context?.scaleBy(x: 1.0, y: -1.0) // 反转坐标系
  392. context?.scaleBy(x: size.width / pageRect.width, y: size.height / pageRect.height) // 缩放
  393. context?.drawPDFPage(pdfPage)
  394. context?.restoreGState()
  395. // 创建NSImage
  396. if let cgImage = context?.makeImage() {
  397. return NSImage(cgImage: cgImage, size: NSSize(width: size.width, height: size.height))
  398. } else {
  399. return nil
  400. }
  401. }
  402. //MARK: - Mouse
  403. override func mouseDown(with event: NSEvent) {
  404. super.mouseDown(with: event)
  405. view.window?.makeFirstResponder(nil)
  406. }
  407. }
  408. //MARK: - ComponentTabsDelegate
  409. extension KMBackgroundPropertyController: ComponentTabsDelegate {
  410. func componentTabsDidSelected(_ view: ComponentTabs, _ property: ComponentTabsProperty) {
  411. if property == textTabProperty {
  412. backgroundData.type = .color
  413. } else if property == fileTabProperty {
  414. backgroundData.type = .image
  415. }
  416. reloadData()
  417. delegate?.backgroundPropertyControllerDidUpdate?(self)
  418. }
  419. }
  420. //MARK: - ComponentCColorDelegate
  421. extension KMBackgroundPropertyController: ComponentCColorDelegate {
  422. func componentCColorDidChooseColor(_ view: NSView, _ color: NSColor?) {
  423. if view == fontColorGroup {
  424. backgroundData.color = color ?? NSColor.clear
  425. }
  426. reloadData()
  427. delegate?.backgroundPropertyControllerDidUpdate?(self)
  428. }
  429. }
  430. //MARK: - ComponentSelectDelegate
  431. extension KMBackgroundPropertyController: ComponentSelectDelegate {
  432. func componentSelectDidSelect(view: ComponentSelect?, menuItemProperty: ComponentMenuitemProperty?) {
  433. if view == appearance_OpacitySelect {
  434. if let text = menuItemProperty?.text {
  435. let result = text.stringByDeleteCharString("%")
  436. backgroundData.opacity = result.stringToCGFloat()/100
  437. }
  438. } else if view == appearance_RotateSelect {
  439. if let text = menuItemProperty?.text {
  440. let result = text.stringByDeleteCharString("°")
  441. backgroundData.rotation = result.stringToCGFloat()
  442. }
  443. } else if view == appearanceScaleSelect {
  444. if let text = menuItemProperty?.text {
  445. let result = text.stringByDeleteCharString("%")
  446. backgroundData.scale = result.stringToCGFloat()/100
  447. }
  448. }
  449. reloadData()
  450. delegate?.backgroundPropertyControllerDidUpdate?(self)
  451. }
  452. func componentSelectTextDidEndEditing(_ view: ComponentSelect) {
  453. if view == appearance_OpacitySelect {
  454. if let text = appearance_OpacitySelect.properties.text {
  455. let result = text.stringByDeleteCharString("%")
  456. backgroundData.opacity = result.stringToCGFloat()/100
  457. }
  458. } else if view == appearance_RotateSelect {
  459. if let text = appearance_RotateSelect.properties.text {
  460. let result = text.stringByDeleteCharString("°")
  461. backgroundData.rotation = result.stringToCGFloat()
  462. }
  463. } else if view == appearanceScaleSelect {
  464. if let text = appearanceScaleSelect.properties.text {
  465. let result = text.stringByDeleteCharString("%")
  466. backgroundData.scale = min(10, result.stringToCGFloat()/100)
  467. }
  468. }
  469. reloadData()
  470. delegate?.backgroundPropertyControllerDidUpdate?(self)
  471. }
  472. }
  473. //MARK: - ComponentCPositionDelegate
  474. extension KMBackgroundPropertyController: ComponentCPositionDelegate {
  475. func componentCPositionDidChoose(_ view: NSView, _ row: Int, _ column: Int) {
  476. if view == positionItemView {
  477. if row == 0 {
  478. backgroundData.verticalMode = 2
  479. } else if row == 1 {
  480. backgroundData.verticalMode = 1
  481. } else if row == 2 {
  482. backgroundData.verticalMode = 0
  483. }
  484. if column == 0 {
  485. backgroundData.horizontalMode = 0
  486. } else if column == 1 {
  487. backgroundData.horizontalMode = 1
  488. } else if column == 2 {
  489. backgroundData.horizontalMode = 2
  490. }
  491. }
  492. reloadData()
  493. delegate?.backgroundPropertyControllerDidUpdate?(self)
  494. }
  495. }
  496. //MARK: - ComponentInputNumberDelegate
  497. extension KMBackgroundPropertyController: ComponentInputNumberDelegate {
  498. func componentInputNumberDidValueChanged(inputNumber: ComponentInputNumber?) {
  499. if inputNumber == positionXInput {
  500. if let text = inputNumber?.properties.text {
  501. backgroundData.horizontalSpace = text.stringToCGFloat()
  502. }
  503. } else if inputNumber == positionYInput {
  504. if let text = inputNumber?.properties.text {
  505. backgroundData.verticalSpace = text.stringToCGFloat()
  506. }
  507. }
  508. reloadData()
  509. delegate?.backgroundPropertyControllerDidUpdate?(self)
  510. }
  511. }