// // KMWatermarkAdjectiveStepper.swift // PDF Master // // Created by tangchao on 2022/12/18. // import Cocoa typealias KMWatermarkAdjectiveStepperValueDidChange = (_ value: Double) -> () class KMWatermarkAdjectiveStepper: NSView { var textField = NSTextField() var stepper = NSStepper() var value: Double { get { return textField.doubleValue } set { textField.doubleValue = newValue stepper.doubleValue = newValue } } var enabled: Bool { get { return textField.isEnabled } set { textField.isEnabled = newValue textField.isEditable = newValue stepper.isEnabled = newValue } } var valueDidChange: KMWatermarkAdjectiveStepperValueDidChange! override init(frame frameRect: NSRect) { super.init(frame: frameRect) initSubViews() } required init?(coder: NSCoder) { super.init(coder: coder) initSubViews() } func initSubViews() { addSubview(textField) addSubview(stepper) textField.focusRingType = .none textField.doubleValue = 0 textField.delegate = self textField.backgroundColor = NSColor.clear textField.cell?.isBordered = false // textField.formatter = TextFieldFormatter() stepper.target = self stepper.action = #selector(valueChanged) stepper.doubleValue = 0.0 stepper.minValue = -1000 stepper.maxValue = 1000 stepper.increment = 1 stepper.appearance = NSAppearance(named: .aqua) } override func layout() { super.layout() let width: CGFloat = NSWidth(self.bounds) let height: CGFloat = NSHeight(self.bounds) let stepperWidth: CGFloat = 12 stepper.frame = NSMakeRect(width-stepperWidth,0, stepperWidth, height) let textFieldX: CGFloat = 4 let textFieldHeight: CGFloat = 20 textField.frame = NSMakeRect(textFieldX, (height-textFieldHeight)*0.5, width-stepperWidth-textFieldX, textFieldHeight) } @objc func valueChanged(sender: NSStepper) { textField.doubleValue = sender.doubleValue guard let callback = valueDidChange else { return } callback(textField.doubleValue) } } extension KMWatermarkAdjectiveStepper: NSTextFieldDelegate { func controlTextDidChange(_ obj: Notification) { if (textField.isEqual(to: obj.object)) { var value: Double = textField.doubleValue if (textField.doubleValue < stepper.minValue) { value = stepper.minValue } if (textField.doubleValue > stepper.maxValue) { value = stepper.maxValue } stepper.doubleValue = value // DispatchQueue.main.async { // self.textField.doubleValue = value // } guard let callback = valueDidChange else { return } callback(stepper.doubleValue) } } }