// // KMEditPDFPopToolBarController.swift // PDF Reader Pro // // Created by tangchao on 2024/6/18. // import Cocoa @objc enum KMEditPDFToolbarItemKey: Int { case none case color case fontStyle case fontAdd case fontReduce case fontBold case fontItalic case textAlignment case leftRotate case rightRotate case reverseX // 左右翻转 case reverseY // 上下翻转 case crop case replace case export case alignmentLeft case alignmentRight case alignmentCenterX case alignmentjustifiedX // 左右两端对齐 case alignmentTop case alignmentBottom case alignmentCenterY case alignmentjustifiedY // 上下两端对齐 case separator // 分割线 } class KMEditPDFToolbarModel: NSObject { var itemKey: KMEditPDFToolbarItemKey = .none var isEnabled = true } class KMSeparatorLineView: NSView { var strokeColor: NSColor = .black { didSet { self.needsDisplay = true } } override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) let rect = self.bounds let ctx = NSGraphicsContext.current?.cgContext ctx?.saveGState() ctx?.setLineWidth(1) ctx?.setStrokeColor(self.strokeColor.cgColor) let startP = NSPoint(x: rect.size.width*0.5, y: 6+2) ctx?.move(to: startP) let endP = NSPoint(x: rect.size.width*0.5, y: rect.size.height-8) ctx?.addLine(to: endP) ctx?.strokePath() ctx?.restoreGState() } } struct KMEditPDFToolbarStyle: OptionSet { let rawValue: Int static var text = KMEditPDFToolbarStyle(rawValue: 1 << 0) static var image = KMEditPDFToolbarStyle(rawValue: 1 << 1) } class KMEditPDFPopToolBarController: NSViewController { deinit { KMPrint("KMEditPDFPopToolBarController deinit.") } convenience init() { self.init(nibName: "KMEditPDFPopToolBarController", bundle: nil) } var toolbarView: KMEditPDFToolbarView? var itemKeys: [KMEditPDFToolbarItemKey] = [] { didSet { // self.toolbarView?.reloadData() } } var datas: [KMEditPDFToolbarModel] = [] { didSet { self.toolbarView?.reloadData() } } var fontColor: NSColor? var itemClick: ((KMEditPDFToolbarItemKey, Any?)->Void)? override func viewDidLoad() { super.viewDidLoad() // Do view setup here. self.interfaceThemeDidChanged(NSApp.appearance?.name ?? .aqua) let toolbarView = KMEditPDFToolbarView() self.toolbarView = toolbarView toolbarView.frame = self.view.bounds toolbarView.autoresizingMask = [.width, .height] self.view.addSubview(toolbarView) toolbarView.delegate = self toolbarView.inset = .init(top: 6, left: 4, bottom: 0, right: 0) toolbarView.reloadData() } @objc func _buttonClick(_ sender: NSButton) { let idx = sender.tag if idx >= 0 && idx < self.itemKeys.count { self.itemClick?(self.itemKeys[idx], nil) } } @objc func textAlignmentItemClick(_ sender: NSButton) { let vc = KMTextAlignmentController(nibName: "KMTextAlignmentController", bundle: nil) let createFilePopover: NSPopover = NSPopover.init() createFilePopover.contentViewController = vc // createFilePopover.delegate = self createFilePopover.animates = true createFilePopover.behavior = .semitransient createFilePopover.setValue(true, forKey: "shouldHideAnchor") createFilePopover.show(relativeTo: CGRect(x: sender.bounds.origin.x, y: 20, width: sender.bounds.size.width, height: sender.bounds.size.height), of: sender, preferredEdge: .maxY) vc.itemAction = { [weak self] idx, _ in var data: NSTextAlignment = .left if idx == 0 { data = .left } else if idx == 1 { data = .center } else if idx == 2 { data = .right } self?.itemClick?(.textAlignment, data) createFilePopover.close() } } @objc func colorPanelAction(_ sender: NSColorPanel) { let color = sender.color let colorView = (self.toolbarView?.itemViews.first as? KMEditPDFToolbarItemView)?.view as? KMEditPDFColorView colorView?.colorBtn.layer?.backgroundColor = color.cgColor self.itemClick?(.color, color) } override func interfaceThemeDidChanged(_ appearance: NSAppearance.Name) { super.interfaceThemeDidChanged(appearance) self.view.wantsLayer = true if appearance == .darkAqua { self.view.layer?.backgroundColor = NSColor(red: 37/255.0, green: 37/255.0, blue: 38/255.0, alpha: 1.0).cgColor } else { self.view.layer?.backgroundColor = .white } Task { @MainActor in self.toolbarView?.reloadData() } } } extension KMEditPDFPopToolBarController: KMEditPDFToolbarViewDelegate { func numberOfItems(in toolbarView: KMEditPDFToolbarView) -> Int { return self.datas.count } func toolbarView(_ toolbarView: KMEditPDFToolbarView, viewFor index: Int) -> NSView? { let model = self.datas[index] let itemKey = model.itemKey if itemKey == .color { let colorView = KMEditPDFToolbarItemView() let view = KMEditPDFColorView() view.colorBtn.layer?.backgroundColor = self.fontColor?.cgColor view.itemClick = { [weak self] idx, _ in let panel = NSColorPanel.shared panel.setTarget(self) panel.setAction(#selector(self?.colorPanelAction)) panel.orderFront(nil) } colorView.view = view return colorView } else if itemKey == .fontStyle { let fontStyleView = KMEditPDFToolbarItemView() let viewC = KMDesignSelect.init(withType: .Combox) viewC.isScrollPop = true fontStyleView.view = viewC.view fontStyleView.obj = viewC // if KMAppearance.isDarkMode() { // viewC.background = NSColor(white: 0, alpha: 0.15) // } viewC.borderColor = KMAppearance.Interactive.s0Color() viewC.background = KMAppearance.Layout.l1Color() viewC.background_hov = KMAppearance.Layout.l1Color() viewC.background_focus = KMAppearance.Layout.l1Color() viewC.textColor = KMAppearance.Layout.h1Color() viewC.textColor_hov = KMAppearance.Layout.h1Color() viewC.textColor_focus = KMAppearance.Layout.h1Color() viewC.popViewControllerBackground = KMAppearance.Layout.bgColor() viewC.popViewControllerTextColor = KMAppearance.Layout.h0Color() viewC.popViewControllerEnterFillColor = KMAppearance.Interactive.s0Color() viewC.updateUI() let familyNames = CPDFFont.familyNames viewC.removeAllItems() viewC.addItems(withObjectValues: familyNames) viewC.selectItem(at: 0) viewC.delete = self return fontStyleView } else if itemKey == .separator { let colorView = KMEditPDFToolbarItemView() let view = KMSeparatorLineView() view.strokeColor = KMAppearance.separatorLineColor() colorView.view = view return colorView } else if itemKey == .textAlignment { let colorView = KMEditPDFToolbarItemView() let viewC = KMDesignButton(withType: .Image) colorView.view = viewC.view colorView.obj = viewC viewC.pagination() if KMAppearance.isDarkMode() { viewC.background_hov = NSColor(hex: "#365898") } else { // viewC.background_hov = NSColor(hex: "#EDEEF0") } viewC.target = self viewC.action = #selector(textAlignmentItemClick) viewC.image = NSImage(named: "KMImageNameEditPDFAlignCenterSelect")! return colorView } let colorView = KMEditPDFToolbarItemView() let viewC = KMDesignButton(withType: .Image) colorView.view = viewC.view colorView.obj = viewC viewC.pagination() if KMAppearance.isDarkMode() { viewC.background_hov = NSColor(hex: "#365898") } else { // viewC.background_hov = NSColor(hex: "#EDEEF0") } viewC.tag = index viewC.state = model.isEnabled ? .Norm : .Disabled viewC.target = self viewC.action = #selector(_buttonClick) if itemKey == .fontAdd { viewC.image = NSImage(named: "KMImageNameEditPDFFontAdd")! colorView.popToolTip = NSLocalizedString("Larger font size", comment: "") } else if itemKey == .fontReduce { viewC.image = NSImage(named: "KMImageNameEditPDFFontReduce")! colorView.popToolTip = NSLocalizedString("Reduce font size", comment: "") } else if itemKey == .fontBold { viewC.image = NSImage(named: "KMImageNameEditPDFFontBold")! colorView.popToolTip = NSLocalizedString("Bold font", comment: "") } else if itemKey == .fontItalic { viewC.image = NSImage(named: "KMImageNameEditPDFFontItalic")! colorView.popToolTip = NSLocalizedString("Italic font", comment: "") } else if itemKey == .textAlignment { viewC.image = NSImage(named: "KMImageNameEditPDFAlignCenterSelect")! colorView.popToolTip = NSLocalizedString("Center text", comment: "") } // 图片 else if itemKey == .leftRotate { viewC.image = NSImage(named: "KMImageNameEditPDFLeftRotateNew")! colorView.popToolTip = NSLocalizedString("Rotate left", comment: "") } else if itemKey == .rightRotate { viewC.image = NSImage(named: "KMImageNameEditPDFRightRotateNew")! colorView.popToolTip = NSLocalizedString("Rotate right", comment: "") } else if itemKey == .reverseX { viewC.image = NSImage(named: "KMImageNameEditPDFReverseX")! colorView.popToolTip = NSLocalizedString("Flip horizontal", comment: "") } else if itemKey == .reverseY { viewC.image = NSImage(named: "KMImageNameEditPDFReverseY")! colorView.popToolTip = NSLocalizedString("Flip vertical", comment: "") } else if itemKey == .crop { viewC.image = NSImage(named: "KMImageNameEditPDFCrop")! colorView.popToolTip = NSLocalizedString("Crop", comment: "") } else if itemKey == .replace { viewC.image = NSImage(named: "KMImageNameEditPDFReplace")! colorView.popToolTip = NSLocalizedString("Replace", comment: "") } else if itemKey == .export { viewC.image = NSImage(named: "KMImageNameEditPDFExport")! colorView.popToolTip = NSLocalizedString("Export file", comment: "") } // 对齐 else if itemKey == .alignmentLeft { viewC.image = NSImage(named: "KMImageNameEditPDFImage45_1")! colorView.popToolTip = NSLocalizedString("Align left", comment: "") } else if itemKey == .alignmentCenterX { viewC.image = NSImage(named: "KMImageNameEditPDFImage46_1")! colorView.popToolTip = NSLocalizedString("Align center", comment: "") } else if itemKey == .alignmentRight { viewC.image = NSImage(named: "KMImageNameEditPDFImage47_1")! colorView.popToolTip = NSLocalizedString("Align right", comment: "") } else if itemKey == .alignmentjustifiedX { viewC.image = NSImage(named: "KMImageNameEditPDFImage21_1")! colorView.popToolTip = NSLocalizedString("Align both ends", comment: "") } else if itemKey == .alignmentTop { viewC.image = NSImage(named: "KMImageNameEditPDFImage48_1")! colorView.popToolTip = NSLocalizedString("Align top", comment: "") } else if itemKey == .alignmentCenterY { viewC.image = NSImage(named: "KMImageNameEditPDFImage49_1")! colorView.popToolTip = NSLocalizedString("Align center in vertical", comment: "") } else if itemKey == .alignmentBottom { viewC.image = NSImage(named: "KMImageNameEditPDFImage50_1")! colorView.popToolTip = NSLocalizedString("Align bottom", comment: "") } else if itemKey == .alignmentjustifiedY { viewC.image = NSImage(named: "KMImageNameEditPDFImage20_1")! colorView.popToolTip = NSLocalizedString("Align ends in vertical", comment: "") } return colorView } func toolbarView(_ toolbarView: KMEditPDFToolbarView, sizeForItemAt index: Int) -> NSSize { let itemKey = self.itemKeys[index] if itemKey == .color { return NSMakeSize(56, 32) } else if itemKey == .fontStyle { return NSMakeSize(148, 32) } else if itemKey == .separator { return NSMakeSize(16, 32) } return NSMakeSize(32, 32) } } extension KMEditPDFPopToolBarController: KMSelectPopButtonDelegate { func km_comboBoxSelectionDidChange(_ obj: KMDesignSelect) { self.itemClick?(.fontStyle, obj.stringValue) } func km_controlTextDidEndEditing(_ obj: KMDesignSelect) { } }