// // MenuBar.swift // MacBackend // // Created by david-swift on 08.09.2024. // import AppKit /// A structure representing the menu bar. public struct MenuBar: MacSceneElement { /// The window's identifier. public var id: String /// The window's content. var content: Body /// The app menu. var app: Body /// The window menu. var window: Body /// The help menu. var help: Body /// Create a menu bar. /// - Parameters: /// - id: The identifier. /// - content: The content. /// - app: The app menu. /// - window: The window menu. /// - help: The help menu. public init( id: String = "main-menu-bar", @ViewBuilder content: @escaping () -> Body, @ViewBuilder app: @escaping () -> Body = { [] }, @ViewBuilder window: @escaping () -> Body = { [] }, @ViewBuilder help: @escaping () -> Body = { [] } ) { self.content = content() self.id = id self.app = app() self.window = window() self.help = help() } /// Set up the initial scene storages. /// - Parameter app: The app storage. public func setupInitialContainers(app: Storage) where Storage: AppStorage { let container = container(app: app) container.show() app.storage.sceneStorage.append(container) } /// The scene storage. /// - Parameter app: The app storage. public func container(app: Storage) -> SceneStorage where Storage: AppStorage { guard let app = app as? MacApp else { return .init(id: id, pointer: nil) { } } let scene = SceneStorage(id: id, pointer: app.mainMenu) { } let data = WidgetData(sceneStorage: scene, appStorage: app) let storage = MenuCollection { self.content }.getMenu(data: data, menu: app.mainMenu) let appStorage = MenuCollection { self.app }.getMenu(data: data, menu: app.appItem.submenu) let windowStorage = MenuCollection { self.window }.getMenu(data: data, menu: app.windowsItem.submenu) let helpStorage = MenuCollection { self.help }.getMenu(data: data, menu: app.helpItem.submenu) scene.content[.mainContent] = [storage] scene.content["app"] = [appStorage] scene.content["window"] = [windowStorage] scene.content["help"] = [helpStorage] return scene } /// Update the stored content. /// - Parameters: /// - storage: The storage to update. /// - app: The app storage. /// - updateProperties: Whether to update the view's properties. public func update( _ storage: SceneStorage, app: Storage, updateProperties: Bool ) where Storage: AppStorage { let data = WidgetData(sceneStorage: storage, appStorage: app) if let content = storage.content["app"]?.first { self.app.updateStorage(content, data: data, updateProperties: updateProperties, type: MenuContext.self) } if let content = storage.content["window"]?.first { self.window.updateStorage(content, data: data, updateProperties: updateProperties, type: MenuContext.self) } if let content = storage.content["help"]?.first { self.help.updateStorage(content, data: data, updateProperties: updateProperties, type: MenuContext.self) } guard let content = storage.content[.mainContent]?.first else { return } self.content.updateStorage(content, data: data, updateProperties: updateProperties, type: MenuContext.self) } }