65 lines
2.0 KiB
Swift
65 lines
2.0 KiB
Swift
//
|
|
// CameraPreviewView.swift
|
|
// Gaze
|
|
//
|
|
// Created by Mike Freno on 1/14/26.
|
|
//
|
|
|
|
import SwiftUI
|
|
import AVFoundation
|
|
|
|
struct CameraPreviewView: NSViewRepresentable {
|
|
let previewLayer: AVCaptureVideoPreviewLayer
|
|
let borderColor: NSColor
|
|
|
|
func makeNSView(context: Context) -> PreviewContainerView {
|
|
let view = PreviewContainerView()
|
|
view.wantsLayer = true
|
|
|
|
// Add the preview layer once
|
|
if view.layer?.sublayers?.first as? AVCaptureVideoPreviewLayer !== previewLayer {
|
|
view.layer?.sublayers?.forEach { $0.removeFromSuperlayer() }
|
|
previewLayer.frame = view.bounds
|
|
view.layer?.addSublayer(previewLayer)
|
|
}
|
|
|
|
updateBorder(view: view, color: borderColor)
|
|
|
|
return view
|
|
}
|
|
|
|
func updateNSView(_ nsView: PreviewContainerView, context: Context) {
|
|
// Only update border color and frame, don't recreate layer
|
|
let currentLayer = nsView.layer?.sublayers?.first as? AVCaptureVideoPreviewLayer
|
|
|
|
if currentLayer !== previewLayer {
|
|
// Layer changed, need to replace
|
|
nsView.layer?.sublayers?.forEach { $0.removeFromSuperlayer() }
|
|
previewLayer.frame = nsView.bounds
|
|
nsView.layer?.addSublayer(previewLayer)
|
|
} else {
|
|
// Same layer, just update frame
|
|
previewLayer.frame = nsView.bounds
|
|
}
|
|
|
|
updateBorder(view: nsView, color: borderColor)
|
|
}
|
|
|
|
private func updateBorder(view: NSView, color: NSColor) {
|
|
view.layer?.borderColor = color.cgColor
|
|
view.layer?.borderWidth = 4
|
|
view.layer?.cornerRadius = 12
|
|
view.layer?.masksToBounds = true
|
|
}
|
|
|
|
class PreviewContainerView: NSView {
|
|
override func layout() {
|
|
super.layout()
|
|
// Update sublayer frames when view is resized
|
|
if let previewLayer = layer?.sublayers?.first as? AVCaptureVideoPreviewLayer {
|
|
previewLayer.frame = bounds
|
|
}
|
|
}
|
|
}
|
|
}
|