Files
Gaze/Gaze/Views/Containers/SettingsWindowPresenter.swift
Michael Freno f8868c9253 pass 1
2026-01-27 14:12:24 -05:00

112 lines
3.1 KiB
Swift

//
// SettingsWindowPresenter.swift
// Gaze
//
// Created by Mike Freno on 1/8/26.
//
import AppKit
import SwiftUI
@MainActor
final class SettingsWindowPresenter {
static let shared = SettingsWindowPresenter()
static let switchTabNotification = Notification.Name("SwitchToSettingsTab")
private var windowController: NSWindowController?
private init() {}
func show(settingsManager: SettingsManager, initialTab: Int = 0) {
if focusExistingWindow(tab: initialTab) { return }
createWindow(settingsManager: settingsManager, initialTab: initialTab)
}
func show(settingsManager: SettingsManager, section: SettingsSection) {
show(settingsManager: settingsManager, initialTab: section.rawValue)
}
func close() {
windowController?.close()
windowController = nil
}
var isVisible: Bool {
windowController?.window?.isVisible ?? false
}
@discardableResult
private func focusExistingWindow(tab: Int?) -> Bool {
guard let window = windowController?.window else {
windowController = nil
return false
}
DispatchQueue.main.async {
if let tab {
NotificationCenter.default.post(
name: Self.switchTabNotification,
object: tab
)
}
NSApp.unhide(nil)
NSApp.activate(ignoringOtherApps: true)
if window.isMiniaturized {
window.deminiaturize(nil)
}
window.makeKeyAndOrderFront(nil)
window.orderFrontRegardless()
}
return true
}
private func createWindow(settingsManager: SettingsManager, initialTab: Int) {
let window = makeWindow()
window.contentView = NSHostingView(
rootView: SettingsWindowView(settingsManager: settingsManager, initialTab: initialTab)
)
let controller = NSWindowController(window: window)
controller.showWindow(nil)
NSApp.unhide(nil)
NSApp.activate(ignoringOtherApps: true)
window.makeKeyAndOrderFront(nil)
window.orderFrontRegardless()
windowController = controller
}
private func makeWindow() -> NSWindow {
let window = NSWindow(
contentRect: NSRect(
x: 0, y: 0,
width: AdaptiveLayout.Window.defaultWidth,
height: AdaptiveLayout.Window.defaultHeight
),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered,
defer: false
)
window.identifier = WindowIdentifiers.settings
window.titleVisibility = .hidden
window.titlebarAppearsTransparent = true
window.toolbarStyle = .unified
window.showsToolbarButton = false
window.center()
window.setFrameAutosaveName("SettingsWindow")
window.isReleasedWhenClosed = false
window.collectionBehavior = [
.managed, .participatesInCycle, .moveToActiveSpace, .fullScreenAuxiliary,
]
return window
}
}