blob: 6f75ebd0b5e831098cdc7e623197cce535f257b6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import SwiftUI
import CompositorServices
import QIOSIntegrationPlugin
import RealityKit
struct QIOSSwiftApplication: App {
@UIApplicationDelegateAdaptor private var appDelegate: QIOSApplicationDelegate
var body: some SwiftUI.Scene {
WindowGroup() {
ImmersiveSpaceControlView()
}
ImmersiveSpace(id: "QIOSImmersiveSpace") {
CompositorLayer(configuration: QIOSLayerConfiguration()) { layerRenderer in
QIOSIntegration.instance().renderCompositorLayer(layerRenderer)
}
}
// CompositorLayer immersive spaces are always full, and should not need
// to set the immersion style, but lacking this we get a warning in the
// console about not being able to "configure an immersive space with
// selected style 'AutomaticImmersionStyle' since it is not in the list
// of supported styles for this type of content: 'FullImmersionStyle'."
.immersionStyle(selection: .constant(.full), in: .full)
}
}
public struct QIOSLayerConfiguration: CompositorLayerConfiguration {
public func makeConfiguration(capabilities: LayerRenderer.Capabilities,
configuration: inout LayerRenderer.Configuration) {
// Use reflection to pull out underlying C handles
// FIXME: Use proper bridging APIs when available
let capabilitiesMirror = Mirror(reflecting: capabilities)
let configurationMirror = Mirror(reflecting: configuration)
QIOSIntegration.instance().configureCompositorLayer(
capabilitiesMirror.descendant("c_capabilities") as? cp_layer_renderer_capabilities_t,
configurationMirror.descendant("box", "value") as? cp_layer_renderer_configuration_t
)
}
}
public func runSwiftAppMain() {
QIOSSwiftApplication.main()
}
public class ImmersiveState: ObservableObject {
static let shared = ImmersiveState()
@Published var showImmersiveSpace: Bool = false
}
struct ImmersiveSpaceControlView: View {
@ObservedObject private var immersiveState = ImmersiveState.shared
@Environment(\.openImmersiveSpace) var openImmersiveSpace
@Environment(\.dismissImmersiveSpace) var dismissImmersiveSpace
var body: some View {
VStack {}
.onChange(of: immersiveState.showImmersiveSpace) { _, newValue in
Task {
if newValue {
await openImmersiveSpace(id: "QIOSImmersiveSpace")
} else {
await dismissImmersiveSpace()
}
}
}
}
}
public class ImmersiveSpaceManager : NSObject {
@objc public static func openImmersiveSpace() {
ImmersiveState.shared.showImmersiveSpace = true
}
@objc public static func dismissImmersiveSpace() {
ImmersiveState.shared.showImmersiveSpace = false
}
}
|