Files

112 lines
2.9 KiB
Swift

//
// 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<CGRect>) {
self.setupLayer()
}
}