// // KMPopUpButton.swift // PDF Reader Pro // // Created by lizhe on 2023/10/9. // import Cocoa @objc enum KMPopUpButtonType: Int { case table = 0 case arrowDown = 1 case arrowUpDown = 2 case noArrow = 3 } @objcMembers class KMPopUpButton: NSPopUpButton { var buttonImage: NSImage? var type: KMPopUpButtonType = .arrowUpDown { didSet { switch type { case .table, .arrowDown, .arrowUpDown: wantsLayer = true layer?.borderWidth = 1.0 layer?.cornerRadius = 4.0 layer?.borderColor = KMAppearance.Layout.bgColor().cgColor bezelStyle = .shadowlessSquare case .noArrow: break } } } override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) var frameSize = bounds var image = NSImage(named: KMImageNameUXIconBtnArrowUpdown) var titleFloat: CGFloat = 8.0 switch type { case .table: KMAppearance.Layout.l1Color().setFill() frameSize.fill() if let tableImg = self.buttonImage { var tableRect = NSZeroRect tableRect.size = tableImg.size var p1 = frameSize.origin p1.x += frameSize.size.width - tableImg.size.width - 8 p1.y += (frameSize.size.height - tableImg.size.height) / 2 tableImg.draw(in: NSMakeRect(8, 4, tableImg.size.width, tableImg.size.height), from: tableRect, operation: .sourceOver, fraction: 1.0, respectFlipped: true, hints: nil) titleFloat += tableImg.size.width + 9.0 // 对选中的item设置勾选 for item in super.itemArray { if item == selectedItem { item.state = .on } else { item.state = .off } } let title = selectedItem?.title as NSString? ?? "" let titleSize = title.size(withAttributes: [NSAttributedString.Key.font: font as Any]) let titleY = frameSize.origin.y + (frameSize.size.height - titleSize.height) / 2 var rectTitle = frameSize rectTitle.origin = NSPoint(x: titleFloat, y: titleY) rectTitle.size.height = titleSize.height title.draw(in: rectTitle, withAttributes: [NSAttributedString.Key.foregroundColor: KMAppearance.Layout.h0Color()]) } case .arrowDown: image = NSImage(named: KMImageNameUXIconBtnArrowDown) case .arrowUpDown: break default: break } var rect = NSRect.zero rect.size = CGSize(width: 16.0, height: 16.0) var p = frameSize.origin p.x += frameSize.size.width - 17 p.y += (frameSize.size.height - 16) / 2 image?.draw(in: NSMakeRect(p.x, p.y, 16.0, 16.0), from: rect, operation: .sourceOver, fraction: 1.0, respectFlipped: true, hints: nil) } } class KMPopUpButtonCell: NSPopUpButtonCell { override func edit(withFrame cellFrame: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, event: NSEvent?) { super.edit(withFrame: adjustedFrameToVerticallyCenterText(cellFrame), in: controlView, editor: textObj, delegate: delegate, event: event) } override func select(withFrame cellFrame: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, start selStart: Int, length selLength: Int) { super.select(withFrame: adjustedFrameToVerticallyCenterText(cellFrame), in: controlView, editor: textObj, delegate: delegate, start: selStart, length: selLength) } override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) { super.drawInterior(withFrame: adjustedFrameToVerticallyCenterText(cellFrame), in: controlView) } private func adjustedFrameToVerticallyCenterText(_ frame: NSRect) -> NSRect { let offset = floor((frame.size.height / 2 - (font!.ascender + font!.descender))) return frame.insetBy(dx: 0.0, dy: offset) } }