Files
Mike Renoir 021837e016 premium
2022-05-05 11:43:21 +04:00

132 lines
4.3 KiB
Swift

//
// VisualEffectView.swift
// TGUIKit
//
// Created by Mikhail Filimonov on 27.09.2021.
// Copyright © 2021 Telegram. All rights reserved.
//
import Foundation
import AppKit
open class VisualEffect: NSVisualEffectView {
private let overlay: CALayer = CALayer()
override public init(frame frameRect: NSRect) {
super.init(frame: frameRect)
setup()
}
public init() {
super.init(frame: .zero)
setup()
}
open override var isFlipped: Bool {
return true
}
public var bgColor: NSColor = NSColor.black.withAlphaComponent(0.2) {
didSet {
overlay.backgroundColor = bgColor.cgColor
}
}
func setup() {
self.wantsLayer = true
self.blendingMode = .withinWindow
self.state = .active
self.bgColor = NSColor.black.withAlphaComponent(0.2)
CATransaction.begin()
CATransaction.setDisableActions(true)
self.overlay.frame = bounds
CATransaction.commit()
layer?.addSublayer(self.overlay)
}
open override func updateLayer() {
super.updateLayer()
if #available(macOS 10.13, *) {
guard let backdrop = self.layer?.sublayers?.first else {
return
}
let sublayers = backdrop.sublayers ?? []
for layer in sublayers {
if layer.name != "backdrop" && layer.name != "Backdrop" {
layer.removeFromSuperlayer()
}
}
let allowedKeys: [String] = [
"colorSaturate",
"gaussianBlur"
]
sublayers.first?.filters = sublayers.first?.filters?.filter { filter in
guard let filter = filter as? NSObject else {
return true
}
let filterName = String(describing: filter)
if !allowedKeys.contains(filterName) {
return false
}
return true
}
for sublayer in sublayers {
sublayer.backgroundColor = nil
sublayer.isOpaque = false
}
}
}
public func change(size: NSSize, animated: Bool, _ save: Bool = true, removeOnCompletion: Bool = true, duration: Double = 0.2, timingFunction: CAMediaTimingFunctionName = .easeOut, completion: ((Bool) -> Void)? = nil) {
self._change(size: size, animated: animated, save, removeOnCompletion: removeOnCompletion, duration: duration, timingFunction: timingFunction, completion: completion)
func animate(_ layer: CALayer, main: Bool) -> Void {
if animated {
var presentBounds:NSRect = layer.bounds
let presentation = layer.presentation()
if let presentation = presentation, layer.animation(forKey:"bounds") != nil {
presentBounds.size.width = NSWidth(presentation.bounds)
presentBounds.size.height = NSHeight(presentation.bounds)
}
layer.animateBounds(from: presentBounds, to: NSMakeRect(0, 0, size.width, size.height), duration: duration, timingFunction: timingFunction, removeOnCompletion: removeOnCompletion, completion: main ? completion : nil)
} else {
layer.removeAnimation(forKey: "bounds")
}
}
guard let backdrop = self.layer?.sublayers?.first else {
return
}
animate(backdrop, main: true)
let sublayers = backdrop.sublayers ?? []
for layer in sublayers {
animate(layer, main: false)
}
if animated {
animate(overlay, main: false)
} else {
CATransaction.begin()
CATransaction.setDisableActions(true)
self.overlay.frame = bounds
CATransaction.commit()
}
}
open override func layout() {
super.layout()
CATransaction.begin()
CATransaction.setDisableActions(true)
self.overlay.frame = bounds
CATransaction.commit()
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}