// // NSButton+CustomAppearance.swift // PDF Reader Pro // // Created by kdanmobile on 2023/10/26. // import Foundation let NSButtonAddHoverKey = "NSButtonAddHoverKey" let NSButtonTrackingAreaKey = "NSButtonTrackingAreaKey" var placeholderImage: NSImage? extension NSButton{ var addHoverEffect: Bool { get { return (objc_getAssociatedObject(self, NSButtonAddHoverKey) as? NSNumber)?.boolValue ?? false } set { removeTrackingArea(self.neededTrackingArea ?? NSTrackingArea()) if newValue { addNewTrackingArea() } objc_setAssociatedObject(self, NSButtonAddHoverKey, NSNumber(value: newValue), .OBJC_ASSOCIATION_RETAIN) } } var neededTrackingArea: NSTrackingArea? { get { return objc_getAssociatedObject(self, NSButtonTrackingAreaKey) as? NSTrackingArea } set { objc_setAssociatedObject(self, NSButtonTrackingAreaKey, newValue, .OBJC_ASSOCIATION_RETAIN) } } func addNewTrackingArea() { self.wantsLayer = true let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .inVisibleRect, .activeAlways], owner: self, userInfo: nil) self.addTrackingArea(trackingArea) self.neededTrackingArea = trackingArea } open override func mouseExited(with event: NSEvent) { super.mouseExited(with: event) if self.addHoverEffect { if !self.isEnabled { return } if (self.image != nil) && (self.alternateImage != nil) { self.alternateImage = self.image self.image = placeholderImage } } } open override func mouseEntered(with event: NSEvent) { super.mouseEntered(with: event) if self.addHoverEffect { if !self.isEnabled { return } if (self.image != nil) && (self.alternateImage != nil) { placeholderImage = self.image self.image = self.alternateImage } } } }