Files

163 lines
5.5 KiB
Swift
Raw Permalink Normal View History

2026-07-27 20:11:52 -07:00
//
// AudioMixerViewController.swift
// XIONControlPanel
//
import UIKit
import WebKit
final class AudioMixerViewController: UIViewController, WKNavigationDelegate
{
static let controlsWidth: CGFloat = 54.0
var closeHandler: (() -> Void)?
private static let mixerURL = URL(string: "http://avmotu.localdomain/#touch-console")!
private static let accentColor = UIColor(red: 0.0, green: 0.95, blue: 0.95, alpha: 1.0)
private let _panelView = UIView(frame: .zero)
private let _webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
private let _closeButton = UIButton(type: .custom)
private let _refreshButton = UIButton(type: .custom)
private let _loadingProgressView = UIProgressView(progressViewStyle: .bar)
private var _progressObservation: NSKeyValueObservation?
override func loadView()
{
view = UIView(frame: .zero)
view.backgroundColor = .clear
view.clipsToBounds = false
}
override func viewDidLoad()
{
super.viewDidLoad()
_panelView.backgroundColor = .black
_panelView.layer.borderColor = Self.accentColor.withAlphaComponent(0.65).cgColor
_panelView.layer.borderWidth = 1.0
_panelView.layer.shadowColor = UIColor.black.cgColor
_panelView.layer.shadowOpacity = 0.95
_panelView.layer.shadowRadius = 116.0
_panelView.layer.shadowOffset = CGSize(width: -10.0, height: 0.0)
view.addSubview(_panelView)
_webView.navigationDelegate = self
_webView.isOpaque = false
_webView.backgroundColor = .black
_webView.scrollView.backgroundColor = .black
_webView.allowsBackForwardNavigationGestures = false
_panelView.addSubview(_webView)
_configureControlTab(_closeButton, accessibilityLabel: "Close Mixer")
_closeButton.setTitle("X", for: .normal)
_closeButton.titleLabel?.font = UIFont(name: "Orbitron-Medium", size: 18.0)
_closeButton.accessibilityIdentifier = "audio.close"
_closeButton.addTarget(self, action: #selector(_close), for: .touchUpInside)
view.addSubview(_closeButton)
_configureControlTab(_refreshButton, accessibilityLabel: "Refresh Mixer")
let refreshImage = UIImage(
systemName: "arrow.clockwise",
withConfiguration: UIImage.SymbolConfiguration(pointSize: 20.0, weight: .medium)
)
_refreshButton.setImage(refreshImage, for: .normal)
_refreshButton.tintColor = Self.accentColor
_refreshButton.accessibilityIdentifier = "audio.refresh"
_refreshButton.addTarget(self, action: #selector(_refresh), for: .touchUpInside)
view.addSubview(_refreshButton)
_loadingProgressView.progressTintColor = Self.accentColor
_loadingProgressView.trackTintColor = UIColor(white: 0.15, alpha: 1.0)
_panelView.addSubview(_loadingProgressView)
_progressObservation = _webView.observe(
\.estimatedProgress,
options: [.new]
) { [weak self] webView, _ in
guard let self else { return }
let progress = Float(webView.estimatedProgress)
self._loadingProgressView.setProgress(progress, animated: true)
self._loadingProgressView.isHidden = progress >= 1.0
}
_loadMixer()
}
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
let contentFrame = CGRect(
x: Self.controlsWidth,
y: 0.0,
width: max(0.0, view.bounds.width - Self.controlsWidth),
height: view.bounds.height
)
_panelView.frame = contentFrame
_panelView.layer.shadowPath = UIBezierPath(rect: _panelView.bounds).cgPath
_webView.frame = _panelView.bounds
_loadingProgressView.frame = CGRect(
x: 1.0,
y: 1.0,
width: max(0.0, _panelView.bounds.width - 2.0),
height: 2.0
)
let tabHeight: CGFloat = 54.0
let tabSpacing: CGFloat = 5.0
let tabTop: CGFloat = 16.0
_closeButton.frame = CGRect(
x: 0.0,
y: tabTop,
width: Self.controlsWidth + 1.0,
height: tabHeight
)
_refreshButton.frame = CGRect(
x: 0.0,
y: _closeButton.frame.maxY + tabSpacing,
width: Self.controlsWidth + 1.0,
height: tabHeight
)
view.bringSubviewToFront(_closeButton)
view.bringSubviewToFront(_refreshButton)
}
private func _configureControlTab(_ button: UIButton, accessibilityLabel: String)
{
button.backgroundColor = UIColor(white: 0.2, alpha: 1.0)
button.setTitleColor(Self.accentColor, for: .normal)
button.accessibilityTraits = .button
button.accessibilityLabel = accessibilityLabel
button.layer.borderColor = Self.accentColor.withAlphaComponent(0.65).cgColor
button.layer.borderWidth = 1.0
}
private func _loadMixer()
{
_loadingProgressView.isHidden = false
_loadingProgressView.progress = 0.0
let request = URLRequest(
url: Self.mixerURL,
cachePolicy: .reloadIgnoringLocalCacheData,
timeoutInterval: 30.0
)
_webView.load(request)
}
@objc private func _close()
{
closeHandler?()
}
@objc private func _refresh()
{
if _webView.url == nil {
_loadMixer()
} else {
_webView.reload()
}
}
}