|
|
@ -3,11 +3,11 @@ import QuartzCore |
|
|
|
|
|
|
|
|
public enum HUDState { |
|
|
public enum HUDState { |
|
|
case hidden |
|
|
case hidden |
|
|
case recording(level: Float, liveText: String? = nil, isLagging: Bool = false) |
|
|
|
|
|
case retrying(message: String) |
|
|
|
|
|
|
|
|
case recording(level: Float, isLagging: Bool = false) |
|
|
|
|
|
case retrying |
|
|
case transcribing |
|
|
case transcribing |
|
|
case success(text: String) |
|
|
|
|
|
case error(message: String) |
|
|
|
|
|
|
|
|
case success |
|
|
|
|
|
case error |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public final class HUDOverlayController { |
|
|
public final class HUDOverlayController { |
|
|
@ -15,7 +15,6 @@ public final class HUDOverlayController { |
|
|
|
|
|
|
|
|
private var window: NSPanel? |
|
|
private var window: NSPanel? |
|
|
private var orbView: SiriOrbView? |
|
|
private var orbView: SiriOrbView? |
|
|
private var statusLabel: NSTextField? |
|
|
|
|
|
private var isVisible = false |
|
|
private var isVisible = false |
|
|
|
|
|
|
|
|
private init() { |
|
|
private init() { |
|
|
@ -25,8 +24,9 @@ public final class HUDOverlayController { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private func setupWindow() { |
|
|
private func setupWindow() { |
|
|
|
|
|
let size: CGFloat = 84 |
|
|
let panel = NSPanel( |
|
|
let panel = NSPanel( |
|
|
contentRect: NSRect(x: 0, y: 0, width: 220, height: 96), |
|
|
|
|
|
|
|
|
contentRect: NSRect(x: 0, y: 0, width: size, height: size), |
|
|
styleMask: [.borderless, .nonactivatingPanel], |
|
|
styleMask: [.borderless, .nonactivatingPanel], |
|
|
backing: .buffered, |
|
|
backing: .buffered, |
|
|
defer: false |
|
|
defer: false |
|
|
@ -42,25 +42,11 @@ public final class HUDOverlayController { |
|
|
let container = NSView(frame: panel.contentView!.bounds) |
|
|
let container = NSView(frame: panel.contentView!.bounds) |
|
|
container.wantsLayer = true |
|
|
container.wantsLayer = true |
|
|
|
|
|
|
|
|
// Siri-like Circular Orb (Center) |
|
|
|
|
|
let orbSize: CGFloat = 58 |
|
|
|
|
|
let orb = SiriOrbView(frame: NSRect(x: (220 - orbSize) / 2, y: 30, width: orbSize, height: orbSize)) |
|
|
|
|
|
|
|
|
// Pure Apple Siri-like Circular Orb (Centered, no bottom text) |
|
|
|
|
|
let orb = SiriOrbView(frame: NSRect(x: 12, y: 12, width: 60, height: 60)) |
|
|
container.addSubview(orb) |
|
|
container.addSubview(orb) |
|
|
self.orbView = orb |
|
|
self.orbView = orb |
|
|
|
|
|
|
|
|
// Caption / Status Pill under the Orb |
|
|
|
|
|
let label = NSTextField(frame: NSRect(x: 10, y: 4, width: 200, height: 22)) |
|
|
|
|
|
label.isBezeled = false |
|
|
|
|
|
label.drawsBackground = false |
|
|
|
|
|
label.isEditable = false |
|
|
|
|
|
label.isSelectable = false |
|
|
|
|
|
label.alignment = .center |
|
|
|
|
|
label.textColor = NSColor.white.withAlphaComponent(0.9) |
|
|
|
|
|
label.font = NSFont.systemFont(ofSize: 11, weight: .medium) |
|
|
|
|
|
label.stringValue = "" |
|
|
|
|
|
container.addSubview(label) |
|
|
|
|
|
self.statusLabel = label |
|
|
|
|
|
|
|
|
|
|
|
panel.contentView = container |
|
|
panel.contentView = container |
|
|
self.window = panel |
|
|
self.window = panel |
|
|
reposition() |
|
|
reposition() |
|
|
@ -86,59 +72,35 @@ public final class HUDOverlayController { |
|
|
switch state { |
|
|
switch state { |
|
|
case .hidden: |
|
|
case .hidden: |
|
|
self.hide() |
|
|
self.hide() |
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
case .recording(let level, let liveText, let isLagging): |
|
|
|
|
|
|
|
|
case .recording(let level, let isLagging): |
|
|
if !self.isVisible { |
|
|
if !self.isVisible { |
|
|
window.orderFrontRegardless() |
|
|
window.orderFrontRegardless() |
|
|
window.animator().alphaValue = 1.0 |
|
|
window.animator().alphaValue = 1.0 |
|
|
self.isVisible = true |
|
|
self.isVisible = true |
|
|
} |
|
|
} |
|
|
orb.updateAudioLevel(level, isLagging: isLagging) |
|
|
orb.updateAudioLevel(level, isLagging: isLagging) |
|
|
if isLagging { |
|
|
|
|
|
self.statusLabel?.stringValue = "اینترنت ضعیف... در حال دریافت" |
|
|
|
|
|
self.statusLabel?.textColor = NSColor(red: 1.0, green: 0.75, blue: 0.2, alpha: 1.0) |
|
|
|
|
|
} else if let txt = liveText, !txt.isEmpty { |
|
|
|
|
|
// Show compact preview of last few words |
|
|
|
|
|
let words = txt.components(separatedBy: .whitespacesAndNewlines).filter { !$0.isEmpty } |
|
|
|
|
|
let tail = words.suffix(4).joined(separator: " ") |
|
|
|
|
|
self.statusLabel?.stringValue = tail |
|
|
|
|
|
self.statusLabel?.textColor = NSColor.white.withAlphaComponent(0.85) |
|
|
|
|
|
} else { |
|
|
|
|
|
self.statusLabel?.stringValue = "گوش میدهم..." |
|
|
|
|
|
self.statusLabel?.textColor = NSColor.white.withAlphaComponent(0.7) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case .retrying(let message): |
|
|
|
|
|
|
|
|
case .retrying: |
|
|
if !self.isVisible { |
|
|
if !self.isVisible { |
|
|
window.orderFrontRegardless() |
|
|
window.orderFrontRegardless() |
|
|
window.animator().alphaValue = 1.0 |
|
|
window.animator().alphaValue = 1.0 |
|
|
self.isVisible = true |
|
|
self.isVisible = true |
|
|
} |
|
|
} |
|
|
orb.showRetryState() |
|
|
orb.showRetryState() |
|
|
self.statusLabel?.stringValue = message |
|
|
|
|
|
self.statusLabel?.textColor = NSColor(red: 1.0, green: 0.65, blue: 0.1, alpha: 1.0) |
|
|
|
|
|
|
|
|
|
|
|
case .transcribing: |
|
|
case .transcribing: |
|
|
orb.showTranscribingState() |
|
|
orb.showTranscribingState() |
|
|
self.statusLabel?.stringValue = "تبدیل به متن..." |
|
|
|
|
|
self.statusLabel?.textColor = NSColor.white.withAlphaComponent(0.8) |
|
|
|
|
|
|
|
|
|
|
|
case .success(let text): |
|
|
|
|
|
|
|
|
case .success: |
|
|
orb.showSuccessState() |
|
|
orb.showSuccessState() |
|
|
let words = text.components(separatedBy: .whitespacesAndNewlines).filter { !$0.isEmpty } |
|
|
|
|
|
let preview = words.suffix(3).joined(separator: " ") |
|
|
|
|
|
self.statusLabel?.stringValue = preview.isEmpty ? "انجام شد" : preview |
|
|
|
|
|
self.statusLabel?.textColor = NSColor(red: 0.3, green: 0.9, blue: 0.4, alpha: 1.0) |
|
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) { |
|
|
|
|
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.45) { |
|
|
self.hide() |
|
|
self.hide() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
case .error(let msg): |
|
|
|
|
|
|
|
|
case .error: |
|
|
orb.showErrorState() |
|
|
orb.showErrorState() |
|
|
self.statusLabel?.stringValue = msg |
|
|
|
|
|
self.statusLabel?.textColor = NSColor(red: 1.0, green: 0.3, blue: 0.3, alpha: 1.0) |
|
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1.2) { |
|
|
|
|
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) { |
|
|
self.hide() |
|
|
self.hide() |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -149,7 +111,7 @@ public final class HUDOverlayController { |
|
|
DispatchQueue.main.async { [weak self] in |
|
|
DispatchQueue.main.async { [weak self] in |
|
|
guard let self = self, let window = self.window, self.isVisible else { return } |
|
|
guard let self = self, let window = self.window, self.isVisible else { return } |
|
|
NSAnimationContext.runAnimationGroup({ context in |
|
|
NSAnimationContext.runAnimationGroup({ context in |
|
|
context.duration = 0.25 |
|
|
|
|
|
|
|
|
context.duration = 0.22 |
|
|
window.animator().alphaValue = 0.0 |
|
|
window.animator().alphaValue = 0.0 |
|
|
}, completionHandler: { |
|
|
}, completionHandler: { |
|
|
window.orderOut(nil) |
|
|
window.orderOut(nil) |
|
|
@ -160,13 +122,13 @@ public final class HUDOverlayController { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// MARK: - Apple Siri-like Gradient Orb View |
|
|
|
|
|
|
|
|
// MARK: - Dynamic Siri Gradient Orb View with Expanded Audio Reactivity |
|
|
|
|
|
|
|
|
final class SiriOrbView: NSView { |
|
|
final class SiriOrbView: NSView { |
|
|
private let gradientLayer = CAGradientLayer() |
|
|
private let gradientLayer = CAGradientLayer() |
|
|
private let glowLayer = CALayer() |
|
|
private let glowLayer = CALayer() |
|
|
private let backdropLayer = CALayer() |
|
|
private let backdropLayer = CALayer() |
|
|
private var baseRadius: CGFloat = 29 |
|
|
|
|
|
|
|
|
private var baseRadius: CGFloat = 30 |
|
|
|
|
|
|
|
|
override init(frame frameRect: NSRect) { |
|
|
override init(frame frameRect: NSRect) { |
|
|
super.init(frame: frameRect) |
|
|
super.init(frame: frameRect) |
|
|
@ -187,21 +149,21 @@ final class SiriOrbView: NSView { |
|
|
let bounds = self.bounds |
|
|
let bounds = self.bounds |
|
|
baseRadius = bounds.width / 2.0 |
|
|
baseRadius = bounds.width / 2.0 |
|
|
|
|
|
|
|
|
// 1. Soft Outer Glow |
|
|
|
|
|
glowLayer.frame = bounds.insetBy(dx: -10, dy: -10) |
|
|
|
|
|
glowLayer.cornerRadius = (bounds.width + 20) / 2.0 |
|
|
|
|
|
glowLayer.backgroundColor = NSColor(red: 0.0, green: 0.6, blue: 1.0, alpha: 0.35).cgColor |
|
|
|
|
|
glowLayer.shadowColor = NSColor(red: 0.4, green: 0.0, blue: 1.0, alpha: 0.6).cgColor |
|
|
|
|
|
glowLayer.shadowRadius = 14 |
|
|
|
|
|
glowLayer.shadowOpacity = 0.8 |
|
|
|
|
|
|
|
|
// 1. Expanded Halo Outer Glow |
|
|
|
|
|
glowLayer.frame = bounds.insetBy(dx: -16, dy: -16) |
|
|
|
|
|
glowLayer.cornerRadius = (bounds.width + 32) / 2.0 |
|
|
|
|
|
glowLayer.backgroundColor = NSColor(red: 0.0, green: 0.75, blue: 1.0, alpha: 0.45).cgColor |
|
|
|
|
|
glowLayer.shadowColor = NSColor(red: 0.5, green: 0.0, blue: 1.0, alpha: 0.85).cgColor |
|
|
|
|
|
glowLayer.shadowRadius = 18 |
|
|
|
|
|
glowLayer.shadowOpacity = 0.9 |
|
|
glowLayer.shadowOffset = .zero |
|
|
glowLayer.shadowOffset = .zero |
|
|
layer.addSublayer(glowLayer) |
|
|
layer.addSublayer(glowLayer) |
|
|
|
|
|
|
|
|
// 2. Dark Translucent Backdrop |
|
|
|
|
|
|
|
|
// 2. Dark Glass Backdrop |
|
|
backdropLayer.frame = bounds |
|
|
backdropLayer.frame = bounds |
|
|
backdropLayer.cornerRadius = baseRadius |
|
|
backdropLayer.cornerRadius = baseRadius |
|
|
backdropLayer.backgroundColor = NSColor.black.withAlphaComponent(0.65).cgColor |
|
|
|
|
|
backdropLayer.borderColor = NSColor.white.withAlphaComponent(0.2).cgColor |
|
|
|
|
|
|
|
|
backdropLayer.backgroundColor = NSColor.black.withAlphaComponent(0.70).cgColor |
|
|
|
|
|
backdropLayer.borderColor = NSColor.white.withAlphaComponent(0.25).cgColor |
|
|
backdropLayer.borderWidth = 1.0 |
|
|
backdropLayer.borderWidth = 1.0 |
|
|
layer.addSublayer(backdropLayer) |
|
|
layer.addSublayer(backdropLayer) |
|
|
|
|
|
|
|
|
@ -209,15 +171,15 @@ final class SiriOrbView: NSView { |
|
|
gradientLayer.frame = bounds.insetBy(dx: 4, dy: 4) |
|
|
gradientLayer.frame = bounds.insetBy(dx: 4, dy: 4) |
|
|
gradientLayer.cornerRadius = (bounds.width - 8) / 2.0 |
|
|
gradientLayer.cornerRadius = (bounds.width - 8) / 2.0 |
|
|
gradientLayer.colors = [ |
|
|
gradientLayer.colors = [ |
|
|
NSColor(red: 0.0, green: 0.85, blue: 1.0, alpha: 0.95).cgColor, // Cyan |
|
|
|
|
|
NSColor(red: 0.45, green: 0.15, blue: 0.95, alpha: 0.95).cgColor, // Violet |
|
|
|
|
|
NSColor(red: 0.95, green: 0.05, blue: 0.65, alpha: 0.9).cgColor // Magenta |
|
|
|
|
|
|
|
|
NSColor(red: 0.0, green: 0.90, blue: 1.0, alpha: 0.95).cgColor, // Electric Cyan |
|
|
|
|
|
NSColor(red: 0.50, green: 0.15, blue: 1.0, alpha: 0.95).cgColor, // Royal Violet |
|
|
|
|
|
NSColor(red: 1.0, green: 0.05, blue: 0.65, alpha: 0.95).cgColor // Hot Magenta |
|
|
] |
|
|
] |
|
|
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0) |
|
|
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0) |
|
|
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0) |
|
|
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0) |
|
|
layer.addSublayer(gradientLayer) |
|
|
layer.addSublayer(gradientLayer) |
|
|
|
|
|
|
|
|
// Subtle constant breathing idle animation |
|
|
|
|
|
|
|
|
// Continuous smooth rotation |
|
|
startOrbRotation() |
|
|
startOrbRotation() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -225,7 +187,7 @@ final class SiriOrbView: NSView { |
|
|
let rotate = CABasicAnimation(keyPath: "transform.rotation.z") |
|
|
let rotate = CABasicAnimation(keyPath: "transform.rotation.z") |
|
|
rotate.fromValue = 0.0 |
|
|
rotate.fromValue = 0.0 |
|
|
rotate.toValue = 2 * Double.pi |
|
|
rotate.toValue = 2 * Double.pi |
|
|
rotate.duration = 4.0 |
|
|
|
|
|
|
|
|
rotate.duration = 3.5 |
|
|
rotate.repeatCount = .infinity |
|
|
rotate.repeatCount = .infinity |
|
|
rotate.isRemovedOnCompletion = false |
|
|
rotate.isRemovedOnCompletion = false |
|
|
gradientLayer.add(rotate, forKey: "siriRotate") |
|
|
gradientLayer.add(rotate, forKey: "siriRotate") |
|
|
@ -235,31 +197,36 @@ final class SiriOrbView: NSView { |
|
|
CATransaction.begin() |
|
|
CATransaction.begin() |
|
|
CATransaction.setDisableActions(true) |
|
|
CATransaction.setDisableActions(true) |
|
|
|
|
|
|
|
|
|
|
|
let clamped = CGFloat(min(max(level, 0.0), 1.0)) |
|
|
|
|
|
|
|
|
if isLagging { |
|
|
if isLagging { |
|
|
// Amber warm warning colors |
|
|
|
|
|
|
|
|
// Warm amber pulse for weak internet |
|
|
gradientLayer.colors = [ |
|
|
gradientLayer.colors = [ |
|
|
NSColor(red: 1.0, green: 0.6, blue: 0.0, alpha: 0.95).cgColor, |
|
|
|
|
|
NSColor(red: 1.0, green: 0.3, blue: 0.0, alpha: 0.95).cgColor, |
|
|
|
|
|
NSColor(red: 0.9, green: 0.8, blue: 0.1, alpha: 0.9).cgColor |
|
|
|
|
|
|
|
|
NSColor(red: 1.0, green: 0.65, blue: 0.0, alpha: 0.95).cgColor, |
|
|
|
|
|
NSColor(red: 1.0, green: 0.30, blue: 0.0, alpha: 0.95).cgColor, |
|
|
|
|
|
NSColor(red: 0.95, green: 0.85, blue: 0.1, alpha: 0.9).cgColor |
|
|
] |
|
|
] |
|
|
glowLayer.backgroundColor = NSColor(red: 1.0, green: 0.5, blue: 0.0, alpha: 0.4).cgColor |
|
|
|
|
|
glowLayer.shadowColor = NSColor(red: 1.0, green: 0.4, blue: 0.0, alpha: 0.7).cgColor |
|
|
|
|
|
|
|
|
glowLayer.backgroundColor = NSColor(red: 1.0, green: 0.5, blue: 0.0, alpha: 0.5).cgColor |
|
|
|
|
|
glowLayer.shadowColor = NSColor(red: 1.0, green: 0.4, blue: 0.0, alpha: 0.85).cgColor |
|
|
} else { |
|
|
} else { |
|
|
// Standard vibrant Siri gradient |
|
|
// Standard vibrant Siri gradient |
|
|
gradientLayer.colors = [ |
|
|
gradientLayer.colors = [ |
|
|
NSColor(red: 0.0, green: 0.85, blue: 1.0, alpha: 0.95).cgColor, |
|
|
|
|
|
NSColor(red: 0.45, green: 0.15, blue: 0.95, alpha: 0.95).cgColor, |
|
|
|
|
|
NSColor(red: 0.95, green: 0.05, blue: 0.65, alpha: 0.9).cgColor |
|
|
|
|
|
|
|
|
NSColor(red: 0.0, green: 0.90, blue: 1.0, alpha: 0.95).cgColor, |
|
|
|
|
|
NSColor(red: 0.50, green: 0.15, blue: 1.0, alpha: 0.95).cgColor, |
|
|
|
|
|
NSColor(red: 1.0, green: 0.05, blue: 0.65, alpha: 0.95).cgColor |
|
|
] |
|
|
] |
|
|
glowLayer.backgroundColor = NSColor(red: 0.0, green: 0.6, blue: 1.0, alpha: 0.35).cgColor |
|
|
|
|
|
glowLayer.shadowColor = NSColor(red: 0.4, green: 0.0, blue: 1.0, alpha: 0.6).cgColor |
|
|
|
|
|
|
|
|
glowLayer.backgroundColor = NSColor(red: 0.0, green: 0.75, blue: 1.0, alpha: 0.45).cgColor |
|
|
|
|
|
glowLayer.shadowColor = NSColor(red: 0.5, green: 0.0, blue: 1.0, alpha: 0.85).cgColor |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Audio reactive scale: expand slightly with microphone volume |
|
|
|
|
|
let clamped = CGFloat(min(max(level, 0.0), 1.0)) |
|
|
|
|
|
let scale = 1.0 + (clamped * 0.35) |
|
|
|
|
|
|
|
|
// High-sensitivity Audio Reactive Dynamics (Significantly boosted impact) |
|
|
|
|
|
// Scale expands from 1.0 up to 1.70x with microphone volume |
|
|
|
|
|
let scale = 1.0 + (clamped * 0.70) |
|
|
self.layer?.sublayerTransform = CATransform3DMakeScale(scale, scale, 1.0) |
|
|
self.layer?.sublayerTransform = CATransform3DMakeScale(scale, scale, 1.0) |
|
|
glowLayer.shadowRadius = 14 + (clamped * 12) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Halo shadow radius and intensity expand dramatically |
|
|
|
|
|
glowLayer.shadowRadius = 18 + (clamped * 36) |
|
|
|
|
|
glowLayer.shadowOpacity = Float(0.70 + (clamped * 0.30)) |
|
|
|
|
|
|
|
|
CATransaction.commit() |
|
|
CATransaction.commit() |
|
|
} |
|
|
} |
|
|
@ -269,18 +236,19 @@ final class SiriOrbView: NSView { |
|
|
CATransaction.setDisableActions(false) |
|
|
CATransaction.setDisableActions(false) |
|
|
CATransaction.setAnimationDuration(0.3) |
|
|
CATransaction.setAnimationDuration(0.3) |
|
|
gradientLayer.colors = [ |
|
|
gradientLayer.colors = [ |
|
|
NSColor(red: 1.0, green: 0.55, blue: 0.0, alpha: 0.95).cgColor, |
|
|
|
|
|
|
|
|
NSColor(red: 1.0, green: 0.60, blue: 0.0, alpha: 0.95).cgColor, |
|
|
NSColor(red: 1.0, green: 0.25, blue: 0.0, alpha: 0.95).cgColor, |
|
|
NSColor(red: 1.0, green: 0.25, blue: 0.0, alpha: 0.95).cgColor, |
|
|
NSColor(red: 0.95, green: 0.85, blue: 0.2, alpha: 0.9).cgColor |
|
|
NSColor(red: 0.95, green: 0.85, blue: 0.2, alpha: 0.9).cgColor |
|
|
] |
|
|
] |
|
|
glowLayer.shadowColor = NSColor.orange.cgColor |
|
|
glowLayer.shadowColor = NSColor.orange.cgColor |
|
|
|
|
|
glowLayer.shadowRadius = 28 |
|
|
CATransaction.commit() |
|
|
CATransaction.commit() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func showTranscribingState() { |
|
|
func showTranscribingState() { |
|
|
CATransaction.begin() |
|
|
CATransaction.begin() |
|
|
CATransaction.setDisableActions(true) |
|
|
CATransaction.setDisableActions(true) |
|
|
self.layer?.sublayerTransform = CATransform3DMakeScale(0.95, 0.95, 1.0) |
|
|
|
|
|
|
|
|
self.layer?.sublayerTransform = CATransform3DMakeScale(1.05, 1.05, 1.0) |
|
|
CATransaction.commit() |
|
|
CATransaction.commit() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -289,10 +257,11 @@ final class SiriOrbView: NSView { |
|
|
CATransaction.setDisableActions(false) |
|
|
CATransaction.setDisableActions(false) |
|
|
CATransaction.setAnimationDuration(0.2) |
|
|
CATransaction.setAnimationDuration(0.2) |
|
|
gradientLayer.colors = [ |
|
|
gradientLayer.colors = [ |
|
|
NSColor(red: 0.2, green: 0.9, blue: 0.4, alpha: 0.95).cgColor, |
|
|
|
|
|
NSColor(red: 0.0, green: 0.7, blue: 0.8, alpha: 0.95).cgColor |
|
|
|
|
|
|
|
|
NSColor(red: 0.1, green: 0.95, blue: 0.45, alpha: 0.95).cgColor, |
|
|
|
|
|
NSColor(red: 0.0, green: 0.80, blue: 0.90, alpha: 0.95).cgColor |
|
|
] |
|
|
] |
|
|
glowLayer.shadowColor = NSColor.green.cgColor |
|
|
glowLayer.shadowColor = NSColor.green.cgColor |
|
|
|
|
|
glowLayer.shadowRadius = 24 |
|
|
CATransaction.commit() |
|
|
CATransaction.commit() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -305,6 +274,7 @@ final class SiriOrbView: NSView { |
|
|
NSColor(red: 0.8, green: 0.0, blue: 0.3, alpha: 0.95).cgColor |
|
|
NSColor(red: 0.8, green: 0.0, blue: 0.3, alpha: 0.95).cgColor |
|
|
] |
|
|
] |
|
|
glowLayer.shadowColor = NSColor.red.cgColor |
|
|
glowLayer.shadowColor = NSColor.red.cgColor |
|
|
|
|
|
glowLayer.shadowRadius = 24 |
|
|
CATransaction.commit() |
|
|
CATransaction.commit() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -312,6 +282,7 @@ final class SiriOrbView: NSView { |
|
|
CATransaction.begin() |
|
|
CATransaction.begin() |
|
|
CATransaction.setDisableActions(true) |
|
|
CATransaction.setDisableActions(true) |
|
|
self.layer?.sublayerTransform = CATransform3DIdentity |
|
|
self.layer?.sublayerTransform = CATransform3DIdentity |
|
|
|
|
|
glowLayer.shadowRadius = 18 |
|
|
CATransaction.commit() |
|
|
CATransaction.commit() |
|
|
} |
|
|
} |
|
|
} |
|
|
} |