// // KMTextImageButtonVC.swift // PDF Reader Pro // // Created by wanjun on 2023/2/3. // import Cocoa @objc enum KMTextImageButtonType : Int { case None = 0 case Up case Left case Down case Right } typealias moveCallback = (_ mouseEntered: Bool) -> Void class KMMoveBox: NSBox { var move: moveCallback? override func viewDidMoveToWindow() { super.viewDidMoveToWindow() if self.window != nil { self.addTrackingRect(self.bounds, owner: self, userData: nil, assumeInside: false) } } override func setFrameSize(_ newSize: NSSize) { super.setFrameSize(newSize) self.addTrackingRect(NSMakeRect(0, 0, newSize.width, newSize.height), owner: self, userData: nil, assumeInside: false) } override func mouseEntered(with event: NSEvent) { if let callback = move { callback(true) } } override func mouseExited(with event: NSEvent) { if let callback = move { callback(false) } } } class KMTextImageButtonVC: NSViewController { @IBOutlet weak var mainBox: KMMoveBox! @IBOutlet weak var upView: NSView! @IBOutlet weak var leftView: NSView! @IBOutlet weak var downView: NSView! @IBOutlet weak var rightView: NSView! @IBOutlet weak var upImageView: NSImageView! @IBOutlet weak var leftImageView: NSImageView! @IBOutlet weak var downImageView: NSImageView! @IBOutlet weak var rightImageView: NSImageView! @IBOutlet weak var upTextfield: NSTextField! @IBOutlet weak var leftTextfield: NSTextField! @IBOutlet weak var downTextfield: NSTextField! @IBOutlet weak var rightTextfield: NSTextField! @IBOutlet weak var button: NSButton! @IBOutlet weak var upPadding_spacing: NSLayoutConstraint! @IBOutlet weak var upImageHeight: NSLayoutConstraint! @IBOutlet weak var upImageWidth: NSLayoutConstraint! @IBOutlet weak var upItem_spacing: NSLayoutConstraint! @IBOutlet weak var leftPadding_spacing: NSLayoutConstraint! @IBOutlet weak var leftImageHeight: NSLayoutConstraint! @IBOutlet weak var leftImageWidth: NSLayoutConstraint! @IBOutlet weak var leftItem_spacing: NSLayoutConstraint! @IBOutlet weak var downPadding_spacing: NSLayoutConstraint! @IBOutlet weak var downImageHeight: NSLayoutConstraint! @IBOutlet weak var downImageWidth: NSLayoutConstraint! @IBOutlet weak var downItem_spacing: NSLayoutConstraint! @IBOutlet weak var rightPadding_spacing: NSLayoutConstraint! @IBOutlet weak var rightImageHeight: NSLayoutConstraint! @IBOutlet weak var rightImageWidth: NSLayoutConstraint! @IBOutlet weak var rightItem_spacing: NSLayoutConstraint! var image: NSImage = NSImage(named: "KMRadioButtonUnSelect")! // 默认 imageView 图片 var image_hover: NSImage = NSImage(named: "KMRadioButtonUnSelect")! // 悬浮 imageView 图片 var image_click: NSImage = NSImage(named: "KMRadioButtonUnSelect")! // 选中 imageView 图片 var stringValue: String = ""// 内容 var textColor: NSColor = .black // 默认内容颜色 var textColor_hover: NSColor = .black // 悬浮内容颜色 var textColor_click: NSColor = .black // 选中内容颜色 var font: NSFont = NSFont.systemFont(ofSize: 14.0) // 默认 内容字体 var lineHeight: CGFloat = 20.0 // 默认 内容行高 var lineHeight_hover: CGFloat = 20.0 // 悬浮 内容行高 var lineHeight_click: CGFloat = 20.0 // 选中 内容行高 var background: NSColor = .clear// 默认背景颜色 var background_hover: NSColor = .clear// 悬浮背景颜色 var background_click: NSColor = .clear// 选中背景颜色 var borderWidth: Float = 1.0// 默认 边框宽度 var borderWidth_hover: Float = 1.0// 悬浮 边框宽度 var borderWidth_click: Float = 1.0// 选中 边框宽度 var borderColor: NSColor = .clear// 边框颜色 var borderColor_hover: NSColor = .clear// 悬浮边框颜色 var borderColor_click: NSColor = .clear// 选中边框颜色 var cornerRadius: Float = 0.0// 默认 边框圆角 var cornerRadius_hover: Float = 0.0// 悬浮 边框圆角 var cornerRadius_click: Float = 0.0// 选中 边框圆角 var imageWidth: Float = 20.0// 图片宽度 var imageHeight: Float = 20.0// 图片高度 var paddingSpacing: Float = 16.0 var itemSpacing: Float = 8.0 var action: Selector? // 点击事件 var target: AnyObject? // 对象目标 var enabled: Bool = true // 是否可点击 var editable: Bool = false //是否允许编辑 var canHover: Bool = true // 是否可悬浮 var type: KMTextImageButtonType = .Left var state: KMDesignTokenState = .Norm override func viewDidLoad() { super.viewDidLoad() // Do view setup here. updateUI() mainBox.move = { [weak self](mouseEntered: Bool) -> Void in if self != nil { if mouseEntered { if self!.state != .Sel && self!.canHover { self!.state = .Hov self!.updateUI() } } else { if self!.state != .Sel && self!.canHover { self!.state = .Norm self!.updateUI() } } } } } func updateUI() -> Void { let paragraphStyle = NSMutableParagraphStyle() if type == .Up { mainBox.contentView = upView upTextfield.isEditable = editable upTextfield.attributedStringValue = NSAttributedString(string: stringValue, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]) upTextfield.font = font } else if type == .Left { mainBox.contentView = leftView leftTextfield.isEditable = editable leftTextfield.attributedStringValue = NSAttributedString(string: stringValue, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]) leftTextfield.font = font } else if type == .Down { mainBox.contentView = downView downTextfield.isEditable = editable downTextfield.attributedStringValue = NSAttributedString(string: stringValue, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]) downTextfield.font = font } else if type == .Right { mainBox.contentView = rightView rightTextfield.isEditable = editable rightTextfield.attributedStringValue = NSAttributedString(string: stringValue, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]) rightTextfield.font = font } button.isEnabled = enabled if state == .Norm { mainBox.fillColor = background mainBox.borderColor = borderColor if type == .Up { upImageView.image = image upTextfield.textColor = textColor } else if type == .Left { leftImageView.image = image leftTextfield.textColor = textColor } else if type == .Down { downImageView.image = image downTextfield.textColor = textColor } else if type == .Right { rightImageView.image = image rightTextfield.textColor = textColor } mainBox.borderWidth = CGFloat(borderWidth) mainBox.cornerRadius = CGFloat(cornerRadius) paragraphStyle.lineSpacing = lineHeight } else if state == .Hov { mainBox.fillColor = background_hover mainBox.borderColor = borderColor_hover if type == .Up { upImageView.image = image_hover upTextfield.textColor = textColor_hover } else if type == .Left { leftImageView.image = image_hover leftTextfield.textColor = textColor_hover } else if type == .Down { downImageView.image = image_hover downTextfield.textColor = textColor_hover } else if type == .Right { rightImageView.image = image_hover rightTextfield.textColor = textColor_hover } mainBox.borderWidth = CGFloat(borderWidth_hover) mainBox.cornerRadius = CGFloat(cornerRadius_hover) paragraphStyle.lineSpacing = lineHeight_hover } else if state == .Sel { mainBox.fillColor = background_click mainBox.borderColor = borderColor_click if type == .Up { upImageView.image = image_click upTextfield.textColor = textColor_click } else if type == .Left { leftImageView.image = image_click leftTextfield.textColor = textColor_click } else if type == .Down { downImageView.image = image_click downTextfield.textColor = textColor_click } else if type == .Right { rightImageView.image = image_click rightTextfield.textColor = textColor_click } mainBox.borderWidth = CGFloat(borderWidth_click) mainBox.cornerRadius = CGFloat(cornerRadius_click) paragraphStyle.lineSpacing = lineHeight_click } button.target = target button.action = action upImageHeight.constant = CGFloat(imageHeight) upImageWidth.constant = CGFloat(imageWidth) leftImageHeight.constant = CGFloat(imageHeight) leftImageWidth.constant = CGFloat(imageWidth) downImageHeight.constant = CGFloat(imageHeight) downImageWidth.constant = CGFloat(imageWidth) rightImageHeight.constant = CGFloat(imageHeight) rightImageWidth.constant = CGFloat(imageWidth) if type == .Up { upPadding_spacing.constant = CGFloat(paddingSpacing) upItem_spacing.constant = CGFloat(itemSpacing) } else if type == .Left { leftPadding_spacing.constant = CGFloat(paddingSpacing) leftItem_spacing.constant = CGFloat(itemSpacing) } else if type == .Down { downPadding_spacing.constant = CGFloat(paddingSpacing) downItem_spacing.constant = CGFloat(itemSpacing) } else if type == .Right { rightPadding_spacing.constant = CGFloat(paddingSpacing) rightItem_spacing.constant = CGFloat(itemSpacing) } } // MARK: Private Methods }