| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- #if !os(WASI)
- import Foundation
- #endif
- /// A scene that presents a single window.
- public struct Window<Content: View>: WindowingScene {
- public typealias Node = WindowNode<Content>
- /// The title of the window (shown in the title bar on most OSes).
- var title: String
- /// The window's content.
- var content: () -> Content
- /// The window's ID.
- ///
- /// This should never change after creation.
- let id: String
- /// Creates a window scene specifying a title and an ID.
- public init(
- _ title: String,
- id: String,
- @ViewBuilder _ content: @escaping () -> Content
- ) {
- self.id = id
- self.title = title
- self.content = content
- }
- }
- /// The ``SceneGraphNode`` corresponding to a ``Window`` scene.
- public final class WindowNode<Content: View>: SceneGraphNode {
- public typealias NodeScene = Window<Content>
- /// The reference to the underlying window object, which also manages
- /// the window's view graph.
- ///
- /// `nil` if the window is closed.
- var windowReference: WindowReference<Window<Content>>? = nil
- /// The underlying scene.
- private var scene: Window<Content>
- public init<Backend: BaseAppBackend>(
- from scene: Window<Content>,
- backend: Backend,
- environment: EnvironmentValues
- ) {
- self.scene = scene
- let openOnAppLaunch =
- switch environment.defaultLaunchBehavior {
- case .presented: true
- case .automatic, .suppressed: false
- }
- if openOnAppLaunch {
- self.windowReference = WindowReference(
- scene: scene,
- backend: backend,
- environment: environment,
- onClose: { self.windowReference = nil },
- id: scene.id
- )
- }
- }
- public func updateNode(
- _ newScene: NodeScene?,
- environment: EnvironmentValues
- ) -> SceneNodeUpdateResult {
- if let newScene {
- self.scene = newScene
- }
- return .leafScene()
- }
- public func update<Backend: BaseAppBackend>(
- backend: Backend,
- environment: EnvironmentValues
- ) {
- environment.openWindowFunctionsByID.value[scene.id] = { [weak self] in
- guard let self else { return }
- if let windowReference {
- // the window is already open: activate it
- windowReference.activate(backend: backend)
- } else {
- // the window is not open: create a new instance
- let reference = WindowReference(
- scene: scene,
- backend: backend,
- environment: environment,
- onClose: { self.windowReference = nil },
- id: scene.id
- )
- windowReference = reference
- reference.update(
- nil,
- backend: backend,
- environment: environment
- )
- }
- }
- windowReference?.update(
- scene,
- backend: backend,
- environment: environment
- )
- }
- }
|