david-swift e989bea14e
All checks were successful
Deploy Docs / publish (push) Successful in 2m38s
Initial commit
2024-12-02 22:14:13 +01:00

72 lines
2.1 KiB
Swift

//
// Submenu.swift
// MacBackend
//
// Created by david-swift on 22.10.23.
//
import AppKit
/// A submenu widget.
public struct Menu: MenuWidget {
/// The label of the submenu.
var label: String
/// The content of the submenu.
var content: Body
/// Initialize a submenu.
/// - Parameters:
/// - label: The submenu's label.
/// - content: The content of the section.
public init(_ label: String, @ViewBuilder content: () -> Body) {
self.label = label
self.content = content()
}
/// The view storage.
/// - Parameters:
/// - data: The widget data.
/// - type: The type of the views.
/// - Returns: The view storage.
public func container<Data>(
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let item = NSMenuItem()
let menu = NSMenu()
item.submenu = menu
let storage = ViewStorage(item)
let content = MenuCollection { self.content }.getMenu(data: data, menu: menu)
storage.content[.mainContent] = [content]
update(storage, data: data, updateProperties: true, type: type)
return storage
}
/// Update the stored content.
/// - Parameters:
/// - storage: The storage to update.
/// - data: The widget data.
/// - updateProperties: Whether to update the properties.
/// - type: The type of the views.
public func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
if let content = storage.content[.mainContent]?.first {
MenuCollection { self.content }.update(content, data: data, updateProperties: updateProperties, type: type)
}
guard updateProperties, let item = storage.pointer as? NSMenuItem else {
return
}
let previousState = storage.previousState as? Self
if previousState?.label != label {
item.title = label
}
storage.previousState = self
}
}