CommandsModifier.swift 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. extension Scene {
  2. /// Adds menu commands to this scene.
  3. ///
  4. /// The commands will typically be displayed in the system's global menu bar
  5. /// if it has one, or in individual windows' menu bars otherwise.
  6. ///
  7. /// - Parameter commands: The commands to add.
  8. public func commands(@CommandsBuilder _ commands: () -> Commands) -> some Scene {
  9. CommandsModifier(content: self, commands: commands())
  10. }
  11. }
  12. struct CommandsModifier<Content: Scene>: Scene {
  13. typealias Node = CommandsModifierNode<Content>
  14. var content: Content
  15. var commands: Commands
  16. init(content: Content, commands: Commands) {
  17. self.content = content
  18. self.commands = commands
  19. }
  20. }
  21. final class CommandsModifierNode<Content: Scene>: SceneGraphNode {
  22. typealias NodeScene = CommandsModifier<Content>
  23. var commands: Commands
  24. var contentNode: Content.Node
  25. init<Backend: BaseAppBackend>(
  26. from scene: NodeScene,
  27. backend: Backend,
  28. environment: EnvironmentValues
  29. ) {
  30. self.commands = scene.commands
  31. self.contentNode = Content.Node(
  32. from: scene.content,
  33. backend: backend,
  34. environment: environment
  35. )
  36. }
  37. func updateNode(
  38. _ newScene: NodeScene?,
  39. environment: EnvironmentValues
  40. ) -> SceneNodeUpdateResult {
  41. if let newScene {
  42. self.commands = newScene.commands
  43. }
  44. var result = contentNode.updateNode(newScene?.content, environment: environment)
  45. result.preferences.commands = result.preferences.commands.overlayed(with: commands)
  46. return result
  47. }
  48. func update<Backend: BaseAppBackend>(
  49. backend: Backend,
  50. environment: EnvironmentValues
  51. ) {
  52. contentNode.update(
  53. backend: backend,
  54. environment: environment
  55. )
  56. }
  57. }