Add window object for closing
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run

This commit is contained in:
david-swift 2024-12-06 23:10:08 +01:00
parent f77cf5bd34
commit 6e266574b0
2 changed files with 31 additions and 9 deletions

View File

@ -15,7 +15,7 @@ public struct Window: MacSceneElement {
/// The window's identifier. /// The window's identifier.
public var id: String public var id: String
/// The window's content. /// The window's content.
var content: Body var content: (MacWindow) -> Body
/// Whether an instance of the window type should be opened when the app is starting up. /// Whether an instance of the window type should be opened when the app is starting up.
var `open`: Int var `open`: Int
/// The window's title. /// The window's title.
@ -36,14 +36,32 @@ public struct Window: MacSceneElement {
/// - open: The number of instances of the window type when the app is starting. /// - open: The number of instances of the window type when the app is starting.
/// - content: The window's content. /// - content: The window's content.
/// - title: The window's title. /// - title: The window's title.
public init(_ title: String = "", id: String, `open`: Int = 1, @ViewBuilder content: @escaping () -> Body) { public init(
_ title: String = "",
id: String,
`open`: Int = 1,
@ViewBuilder content: @escaping (MacWindow) -> Body
) {
self.title = title self.title = title
self.content = content() self.content = content
self.id = id self.id = id
self.open = open self.open = open
} }
// swiftlint:enable function_default_parameter_at_end // swiftlint:enable function_default_parameter_at_end
/// The window type.
public struct MacWindow {
/// The window.
var window: NSWindow
/// Close the window.
public func close() {
window.close()
}
}
/// Set up the initial scene storages. /// Set up the initial scene storages.
/// - Parameter app: The app storage. /// - Parameter app: The app storage.
public func setupInitialContainers<Storage>(app: Storage) where Storage: AppStorage { public func setupInitialContainers<Storage>(app: Storage) where Storage: AppStorage {
@ -65,7 +83,8 @@ public struct Window: MacSceneElement {
.addObserver(forName: NSWindow.willCloseNotification, object: window, queue: nil) { _ in .addObserver(forName: NSWindow.willCloseNotification, object: window, queue: nil) { _ in
storage.destroy = true storage.destroy = true
} }
let content = content.storage(data: .init(sceneStorage: storage, appStorage: app), type: MacMainView.self) let content = content(.init(window: window))
.storage(data: .init(sceneStorage: storage, appStorage: app), type: MacMainView.self)
if let pointer = content.pointer as? NSView { if let pointer = content.pointer as? NSView {
window.contentView = pointer window.contentView = pointer
} }
@ -89,17 +108,17 @@ public struct Window: MacSceneElement {
app: Storage, app: Storage,
updateProperties: Bool updateProperties: Bool
) where Storage: AppStorage { ) where Storage: AppStorage {
guard let window = storage.pointer as? NSWindow else {
return
}
if let content = storage.content[.mainContent]?.first { if let content = storage.content[.mainContent]?.first {
self.content.updateStorage( self.content(.init(window: window)).updateStorage(
content, content,
data: .init(sceneStorage: storage, appStorage: app), data: .init(sceneStorage: storage, appStorage: app),
updateProperties: updateProperties, updateProperties: updateProperties,
type: MacMainView.self type: MacMainView.self
) )
} }
guard let window = storage.pointer as? NSWindow else {
return
}
guard updateProperties else { guard updateProperties else {
return return
} }
@ -155,3 +174,6 @@ public struct Window: MacSceneElement {
} }
} }
/// The window type.
public typealias MacWindow = Window.MacWindow

View File

@ -27,7 +27,7 @@ struct Demo: App {
@State private var menuPresented = false @State private var menuPresented = false
var scene: Scene { var scene: Scene {
Window("Main", id: "main") { Window("Main", id: "main") { _ in
NavigationSplitView { NavigationSplitView {
List(elements, selection: $selectedElement) { element in List(elements, selection: $selectedElement) { element in
Label(element.id, icon: .system(name: "play.fill")) Label(element.id, icon: .system(name: "play.fill"))