// // RadioBaseButton.swift // PrivadoVPN // // Created by Murad Shabanov on 29.07.2021. // Copyright © 2021 Privado LLC. All rights reserved. // import Foundation import Cocoa // MARK: - RadioBaseButton public class RadioBaseButton: NSButton { /// Oberver frame change to update style private var sizeChangeObserver: NSKeyValueObservation? /// Allow delection for button useful in Check bok stype internal var allowDeselection: Bool { return false } /// Keep the track of Selection and deselction @objc dynamic public var isOn = false { didSet { if self.isOn != oldValue { self.updateSelectionState() self.callDelegate() } } } required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.setup() } public override init(frame: CGRect) { super.init(frame: frame) self.setup() } public convenience init?(type buttonType: NSButton.ButtonType) { return nil } /// Setup intial things required internal func setup() { // Add action here self.addObserverSizeChange() self.setupLayer() } public override func mouseDown(with event: NSEvent) { super.mouseDown(with: event) guard isEnabled else { return } self.selectionAction() } /// Action handler of button for internal use /// /// - Parameter sender: RadioButton @objc internal func selectionAction() { // If toggle enable, change selection state if self.allowDeselection { self.isOn = !self.isOn } else if !isOn { self.isOn = true } } /// Update selection stage as button selected for deselected public func updateSelectionState() { if self.isOn { self.updateActiveLayer() } else { self.updateInactiveLayer() } } /// Setup layer that will for Radio button /// This method can be called mutliple times /// Do the stuff by overriding, then call super class method internal func setupLayer() { self.updateSelectionState() } /// Update active layer as button is selected internal func updateActiveLayer() { } /// Update inative later as button is deselected internal func updateInactiveLayer() { } /// call delegate as button selection state changes internal func callDelegate() { } } // MARK:- frame change handler extension RadioBaseButton { private func addObserverSizeChange() { self.sizeChangeObserver = observe(\RadioBaseButton.frame, changeHandler: self.sizeChangeObseveHandler) } private func sizeChangeObseveHandler(_ object: RadioBaseButton, _ change: NSKeyValueObservedChange) { self.setupLayer() } }